views:

70

answers:

1

Ok, now I can use 2 techniques to launch my threads: Dispatcher and 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

I don't know what is better, but I think I'll use BackgroundWorker, because I suppose there are other argouments about Dispatcher I have to know and I don't feel safe.

Pileggi

My previous post:

Hi everyone!

My application is in WPF / Vb framework 3.5 SP1. I need to execute some methods on asynchronous threads. I know this way:

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

But in this way I have to declare a delegate for every mothod I want to launch on an asynchronous thread, and it's very uncomfortable. I have a lot of method to launch in this way. I know there are the anonymous delegates, but I don't know how to use them in this case. Can you help me? Pileggi

PS. Other information: in this moment I don't need to lookup the status of the process launched in the asynchronous thread. The long operations are some requests to a webservice that can take some seconds every time. There is no problem for the number of threads, because I limit the possibilities for the user to start new threads until one of them is finished. I need the asyncronous threads, among other reasons, because I don't wont to block the application, I want to replace the mouse cursor with a user-control, etc..

A: 

What is it that you're trying to do, that requires you to launch all of these threads? It looks like you're creating the secondary thread just to be able to do GUI updates.

First of all, if you have to create a lot of threads, then you run the risk of running out of available threads pretty quickly. I thought the max was only 64, but the documentation says 250 per process, and it's also settable via GetMaxThreads and SetMaxThreads. Regardless, you need to decide if using the ThreadPool threads (which is what's used when you use BeginInvoke/EndInvoke) is appropriate for you.

How long do your GUI updates take? Are they going to run the entire duration of your application? Can you use a regular thread instead? Look into using a BackgroundWorker for GUI updates if you just need to update status information periodically. In some cases, even DispatcherTimer might do the trick. It just depends on what you want to do.

You also don't show all of your code, but in what's posted, EndInvoke is not called. If you do this and end up throwing an exception, you won't be able to catch it and handle the error properly.

Dave
@Dave: Thank you very much for your interest. I have edited my post adding the answers to your questions. My only problem is that I would like to use the anonymous delegate to write less code, but I don't know how.
pileggi
Well, I would recommend doing a search, then. :) I am not enough of an expert in this area to tell you how you should do it. When I use delegates, I do it the same way as you -- create a delegate and pass its constructor a function that I want to execute in a thread. I don't see anything wrong with it. The only thing that raises my eyebrows is the method by which you're doing GUI updates, which seems a little strange. You should see what others post regarding this approach.
Dave
@Dave: why my GUI updates appear strange at your eyes?
pileggi
@pileggi Just because you launch a thread that does a long set of operations, and then launches another thread to do the GUI updates. GUI can only be updated from the main thread, so it looks like you're using whatever seems convenient for access to the Dispatcher. There are other ways to do GUI updates from threads, like `BackgroundWorker`. Or you can put your results into shared memory, and have your GUI update periodically by reading the shared memory. The memory would have to be protected by a critical secion, but you could always use `ReaderWriterLockSlim` for better performance.
Dave
@Dave: thank you. I see you are very competent about threading models. I used the BackgroundWorker in the past, but now I see I have to study a bit before writing more code. I just ask you this: when I have finded a solution, can I find you again to have an opinion from you? I tell you this because this forum is wonderful, but if you spend too much time for the next post, it's hard to find still someone that answers.
pileggi
@pileggi of course, just post an update to this question. Just because I have noticed a few things, please don't assume that I am *competent*. I make lots of mistakes all of the time. I'm slowly improving with time. :)
Dave
@Dave: for me you are competent :-)
pileggi
@Dave: I have edited my post. I think you will suggest me to use Backgroundworker, but Dispatcher appears me more flexible and complete, if my code is week, could you help me to get it better? Thank you! Pileggi
pileggi