0

Хорошо, теперь я могу использовать 2 метода для запуска моих потоков: Диспетчер и BackgroundWorker.асинхронные потоки и анонимные делегаты

грузоотправитель:

' I launch the asynchronous process 
Dim a As New Action(AddressOf operazioneLunga) 
a.BeginInvoke(Nothing, Nothing) 

' I update the GUI passing some parameters 
Dim a As New Action(Of Integer, String)(AddressOf aggiorna_UI) 
Me.Dispatcher.BeginInvoke(DispatcherPriority.Normal, a, 5, "pippo") 

BackgroundWorker:

Private bw As BackgroundWorker = Nothing 

Private Sub initial() 
    bw = New BackgroundWorker 
    AddHandler bw.DoWork, AddressOf longOp 
    AddHandler bw.RunWorkerCompleted, AddressOf endBGW 
    bw.RunWorkerAsync() 
End Sub 

Private Sub longOp(ByVal sender As Object, ByVal e As DoWorkEventArgs) 
    Dim l As List(Of miaClasse2) = <Long Operation ...> 

    e.Result = l 
End Sub 

Private Sub endBGW(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) 
    Dim l As List(Of miaClasse2) = e.Result 
    Dim be As BindingExpression = BindingOperations.GetBindingExpression(mioDatagrid, DataGrid.ItemsSourceProperty) 
    Dim m As miaClasse1 = DirectCast(be.DataItem, miaClasse1) 
    m.GetData (l) 
    mioDatagrid.UpdateLayout() 
    mioDatagrid.ScrollIntoView (mioDatagrid.Items(0)) 
    RemoveHandler bw.DoWork, AddressOf massiccia 
    RemoveHandler bw.RunWorkerCompleted, AddressOf fineBGW 
    bw.Dispose() 
End Sub 

Я не знаю, что лучше, но я думаю, что я буду использовать BackgroundWorker, потому что я полагаю, есть и другие argouments о Dispatcher I должны знать, и я не чувствую себя в безопасности.

Pileggi

Мой предыдущий пост:

Привет всем!

Мое приложение в среде WPF/Vb 3.5 SP1. Мне нужно выполнить некоторые методы для асинхронных потоков. Я знаю, что это так:

Private Delegate Sub dMassiccia() 
Private Delegate Sub dAggiornaUI() 

Private Sub iniziale() 
    Dim massicciaTemp As New dMassiccia(AddressOf massiccia) 
    massicciaTemp.BeginInvoke(Nothing, Nothing) 
End Sub 

Private Sub massiccia() 
    'long operations... 
    Me.Dispatcher.BeginInvoke(DispatcherPriority.Normal, _ 
    New dAggiornaUI(AddressOf aggiornaUI)) 
End Sub 

Private Sub aggiornaUI() 
    'update the UI... 
End Sub 

Но в этом случае я должен объявить делегат для каждого Mothod я хочу запустить на асинхронном потоке, и это очень неудобно. У меня есть много методов для запуска таким образом. Я знаю, что есть анонимные делегаты, но я не знаю, как их использовать в этом случае. Вы можете мне помочь? Pileggi

PS. Другая информация: в этот момент мне не нужно искать статус процесса, запущенного в асинхронном потоке. Длительные операции - это некоторые запросы к веб-сервису, которые могут занимать несколько секунд каждый раз. Нет проблем для количества потоков, потому что я ограничиваю возможности для пользователя запускать новые потоки, пока один из них не будет завершен. Мне нужны асинхронные темы, среди других причин, потому что я не хочу блокировать приложение, я хочу заменить курсор мыши на пользовательский контроль и т. Д.

ответ

0

Что вы пытаетесь сделать do, для чего вам нужно запустить все эти потоки? Похоже, вы создаете дополнительный поток, чтобы иметь возможность обновлять графические интерфейсы.

Прежде всего, если вам нужно создать лот потоков, то вы рискуете быстро исчерпать доступные потоки. Я думал, что максимальная сумма составляет всего 64, но в документации указано 250 за процесс, а также можно установить через GetMaxThreads и SetMaxThreads. Независимо от того, вам нужно решить, подходит ли вам использование потоков ThreadPool (то, что используется при использовании BeginInvoke/EndInvoke).

Как долго ваши обновления графического интерфейса? Будут ли они исполнять всю продолжительность вашего заявления? Можете ли вы использовать регулярный поток вместо этого? Посмотрите на использование BackgroundWorker для обновления графического интерфейса пользователя, если вам просто нужно периодически обновлять информацию о состоянии. В некоторых случаях даже DispatcherTimer может сделать трюк. Это зависит от того, что вы хотите сделать.

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

+0

@ Dave: Большое спасибо за ваш интерес. Я редактировал свой пост, добавляя ответы на ваши вопросы. Моя единственная проблема в том, что я хотел бы использовать анонимный делегат, чтобы писать меньше кода, но я не знаю, как это сделать. – lamarmora

+0

Ну, я бы рекомендовал сделать поиск.:) Мне не хватает эксперта в этой области, чтобы рассказать вам, как вы должны это делать. Когда я использую делегаты, я делаю это так же, как вы, - создайте делегат и передайте его конструктору функцию, которую я хочу выполнить в потоке. Я не вижу в этом ничего плохого. Единственное, что поднимает мои брови, это метод, с помощью которого вы делаете обновления GUI, что кажется немного странным. Вы должны увидеть, что другие публикуют относительно этого подхода. – Dave

+0

@Dave: почему мои обновления графического интерфейса кажутся странными в ваших глазах? – lamarmora