The right way in MVVM WPF to start a multi-threaded search task

So, I have a task that can be prepared by my GUI, which will retrieve information to populate the ViewModel with a response to a SQL database query. Suppose I want to start this task and save my gui for free to continue other things , and in the meantime play a "search" animation , what is the right way to do this in WPF / MVVM? I assume that you need to run an asynchronous process and install a bool attached to a datatrigger that runs the animation storyboard. But what am I using to start the process? Thread? I'm still new to WPF and just want to make sure that I use the appropriate classes for me.

+7
multithreading wpf mvvm
source share
3 answers

I am using the BackgroundProcess thread to do this.

Here's a link to MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Additional information related to this.

You have three events associated with the BackgroundProcess object: DoWork, ReportProgress, and WorkCompleted.

Now, to use this - and use it with an observable collection - you want to tell the BackgroundProcess object the possibility of PROGRESS REPORT (this is a logical property that I have always explicitly set and also allows cancellation).

Now, to start the process, you call the RunWorkerAsync method. This method has the ability to accept the OBJECT variable in case you need to pass data (if you want more than one value, create a structure that will be passed to RunWorkerAsync).

RunWorkerAsync disconnects from the DoWork event, so the control heads go to your DoWork event handler. Here's the (sanitized) code where I use it from:

Dim dt As System.Data.DataTable dt = da.GetDataTable(sql, System.Data.CommandType.Text, params) For Each row As System.Data.DataRow In dt.Rows If loadQuestionsWorker.CancellationPending Then e.Cancel = True Exit Sub End If Dim item As New DataObject // Assign Item Values backgroundProcessObject.ReportProgress(1, item) Next 

What happens here is that I get data from my data layer, and then, until this background process is canceled, I go through the data table, and when I create a new DataObject, I report this object as constructed.

Now, in my ProgressChanged event handler (the ReportProgress method raises the ProgressChanged event), the control is returned to the user interface threads, so I can do things like affect the user interface and add the element I'm reporting an ObservableCollection about.

Finally, in the WorkedCompleted event handler (the corresponding event occurs when the DoWork event handler method is executed before completion). I check if my progress has been canceled (which sometimes means that I want to reset the ObservableCollection), and I may or may not influence the user interface (for example, removing the SEARCH animation.

+8
source share

You can start a new Thread or BackgroundWorker explicitly or use ThreadPool . I do not know what is the recommended way to do this in MVVM ...

If your asynchronous operation fills the ObservableCollection binding to the control, note that you cannot add elements to it in another thread. You need to do this in the dispatch manager thread. Or you can also use this collection , which raises the CollectionChanged event in the corresponding thread

+2
source share
 var t = new Thread((ThreadStart)delegate { DoWork(...) Dispatcher.BeginInvoke((Action)delegate { SomethingOntheUiThread(...) FinishedWork(...); } }); t.Start(); 
+1
source share

All Articles