асинхронные потоки и анонимные делегаты - PullRequest
0 голосов
/ 20 сентября 2010

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

Dispatcher:

' 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, потому что, полагаю, есть и другие аргументы в отношении Dispatcher, которые я должен знать и не чувствую себя в безопасности.

Pileggi

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

Привет всем!

Мое приложение в WPF / Vb framework 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

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

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

1 Ответ

0 голосов
/ 20 сентября 2010

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

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

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

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

...