Silverlight: switching service calls and processing files in the background thread

Whether ProcessFile() works on UIThread or on a separate thread. If it is in UIThread, how do I move the file request and ProcessFile () to a separate Thread ?

 var xClient = new ServiceReference1.Service1SoapClient(); xClient.Retrieve_File_Completed += new EventHandler<ServiceReference1.Retrieve_File_CompletedCompletedEventArgs>(xClient_Retrieve_File_Completed); . .//called on Page load foreach(fileName in fileNames) { xClient.Retrieve_FileAsync(fileName); } . . void xClient_Retrieve_File_Completed(object sender, ServiceReference1.Retrieve_File_CompletedCompletedEventArgs e) { //Processing ProcessFile(e.Result[0]); //Is this on UI Thread? } 

EDIT: From the answers it is clear that ProcessFile() running in the user interface thread. How files and request ( ProcessFile() ) can be moved to a separate thread. ProcessFile simply populates some data structures using which user interface changes after all files are received.

+4
source share
2 answers

Service proxies that Visual Studio automatically generates when you use the Add Service Link feature automatically send completed callback events to the thread that initiated the service call.

In your case, this means that xClient_Retrieve_File_Completed actually executing in your UI thread.

Update: It is actually quite difficult to put file requests and file processing on a single thread, and then update the user interface after all requests and processing are complete, because you must save the stream while all the service requests are completed. There is no guarantee that service requests will be completed in the same order in which they are sent, so you need to keep track of the number of completed requests, and only when all requests are completed can you notify the user interface and complete the flow.

For me, this sounds like a fragile and complex design, and unfortunately the CountDownEvent that you can use for such a design does not exist in Silverlight.

Alternatively, you can consider changing the design of your service and ProcessFile so that you can request and process all files at the same time, so you only need to make one service request (if you do not send data loads through the network to and from the service). You can then create a BackgroundWorker ( as Matthew Paul Kilan suggested in his answer ) to process all the files in one shot. Then your code will look something like this:

 // Called on Page load. // Note that there is only one service call with all file names as parameter. xClient.Retrieve_FileAsync(fileNames); // ... // Elsewhere in the class BackgroundWorker _worker; void xClient_Retrieve_File_Completed(object sender, ServiceReference1.Retrieve_File_CompletedCompletedEventArgs e) { _worker = new BackgroundWorker() _worker.DoWork += (sender, args) => { // Only one call to ProcessFile. ProcessFile(e.Result); }; _worker.RunWorkerCompleted += (sender, args) => { // Update UI here }; _worker.RunWorkerAsync(); } 
+2
source

You can determine if code is being executed in the user interface thread using the Dispatcher.CheckAccess () method:

Dispatcher.CheckAccess Method

If the ProcessFile method is an expensive operation, you can try unloading it in BackgroundWorker. Pete Brown perfectly describes how to do this here:

User Interface, Dispatchers, Background Workers, and Network Programming of Asynchronous Networks

+1
source

All Articles