Member 11856456 Ответов: 2

Пытаюсь сделать заказ параллельно по каждому элементу


Я пытаюсь сделать пользовательскую параллель для каждого оператора, чтобы включить его в dll-файл.

Мне трудно создать объект, который отображается как делегат. Мне нужно имя, чтобы перейти в адрес части параллели для каждого оператора.
Я пытаюсь передать имя делегата в виде строки через sub. Проблема в том, что я не могу понять, как сделать переменную результата пригодной для использования в адресе.

Public Sub parallelforeach(startofiteration As Long, endofiteration As Long, subfunctionname As String)
       Dim result As [delegate]


       result = CallByName(Me, subfunctionname, CallType.Get, Nothing)
       ' CallByName()
       Dim numbers() = Enumerable.Range(startofiteration, endofiteration).ToArray
       ' CallByName(yourClassOrObjectName, "NameExample1", CallType.Set, oReader.ReadString)
       ' System.Threading.Tasks.Parallel.ForEach(numbers, processorcount, AddressOf process)
   End Sub



Я получаю эту ошибку,
System.MissingMemberException: 'Public member 'process' on type 'Form1' not found.'


Я пытался найти информацию о делегатах и их адресах. Не так уж много там о том, чего я пытаюсь достичь.

Что я уже пробовал:

Я попытался изменить делегат на объект. Я также попытался изменить type.get на type.method, чтобы посмотреть, поможет ли это.

2 Ответов

Рейтинг:
15

Richard Deeming

Вам нужно создать Action(Of Integer) делегат задается именем метода в текущем классе:

Public Sub ParallelForEach(ByVal startOfIteration As Integer, ByVal endOfIteration As Integer, ByVal subFunctionName As String)
    
    Const flags As BindingFlags = BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Static Or BindingFlags.Instance
    
    ' Find the method with the specified name which accepts a single Integer parameter:
    Dim method As MethodInfo = Me.GetType().GetMethod(subFunctionName, flags, Nothing, New Type() { GetType(Integer) }, Nothing)
    
    If method Is Nothing Then
        Throw New ArgumentException(String.Format("Method '{0}' was not found.", subFunctionName), "subFunctionName")
    End If

    ' Create a delegate of the correct type pointing to the method:
    Dim del As System.Delegate
    If method.IsStatic Then
        del = System.Delegate.CreateDelegate(GetType(Action(Of Integer)), method)
    Else
        del = System.Delegate.CreateDelegate(GetType(Action(Of Integer)), Me, method)
    End If
    
    ' Cast the delegate to the correct type:
    Dim action As Action(Of Integer) = DirectCast(del, Action(Of Integer))
    
    ' NB: Second parameter to Range is the number of items to return, not the last number to return:
    Dim numbers As IEnumerable(Of Integer) = Enumerable.Range(startOfIteration, 1 + endOfIteration - startOfIteration)
    
    System.Threading.Tasks.Parallel.ForEach(numbers, processorCount, action)
End Sub
NB: Параметры к Enumerable.Range являются Integer (32-бит), не Long (64-битовый).

Кроме того, второй параметр-это количество возвращаемых элементов, нет последнее число, которое нужно вернуть. Ваши имена параметров предполагают, что вы передаете последнее возвращаемое число, поэтому вам нужно подстроиться под это.

Поскольку вы повторяете фиксированный набор чисел, вероятно, было бы лучше использовать Параллельно.Для[^] вместо Parallel.ForEach.


Member 11856456

Ричард, я собираюсь все это перевернуть. Не могли бы вы объяснить, что вы подразумеваете под количеством предметов, которые нужно вернуть? Можете ли вы привести пример. и я думаю, что вы правы, мне следует перейти к параллельному утверждению.for вместо этого, является ли установка примера, который вы дали, такой же?

Richard Deeming

Второй параметр к Перечислимый.Диапазон[^] есть count Итератор выдаст такое количество чисел - например, если вы вызовете Enumerable.Range(10, 2), возвращаемый итератор будет производить { 10, 11 }.

Ваше имя параметра - endOfIteration - заставляет меня думать, что вы хотите передать последний номер, чтобы вернуться. Например, если вы прошли (startOfIteration := 10, endOfIteration := 11), вы бы хотели { 10, 11 }, нет { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }.

Richard Deeming

Базовая версия Parallel.For также принимает Action(Of Integer) таким образом , установка будет точно такой же. Вы бы просто заменили последние две строки на:

System.Threading.Tasks.Parallel.For(startOfIteration, 1 + endOfIteration - startOfIteration, action)

Рейтинг:
1

Gerry Schmitz

Есть ли у вашей "формы 1" "публичный" член под названием "Процесс"?

Как насчет частного, который вы можете сделать публичным?

Или добавьте его в форму 1 и посмотрите, что произойдет, когда он будет "вызван".

Цитата:
'? Система.Нарезание резьбы.Задачи.Параллель.По каждому элементу(число, processorcount, оператором addressof процесс)


Member 11856456

да,
Отдельный подпроцесс(я так долго)
конец подводной лодки

Я сменил приватное на публичное и получил новое сообщение:
System.MissingMemberException: "разрешение перегрузки не удалось, потому что ни один доступный "процесс" не принимает такое количество аргументов".