微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – Silverlight:将服务调用和文件处理移动到后台线程

ProcessFile()是在UIThread上运行还是在单独的线程上运行.如果它在UIThread上,如何将文件请求和ProcessFile()移动到单独的线程?

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?
}

编辑:从答案,很明显ProcessFile()在UI线程上运行.如何将文件请求和处理(ProcessFile())移动到单独的Thread. ProcessFile只填充一些数据结构,在收到所有文件后使用这些数据结构更改UI.

解决方法:

使用“添加服务引用”功能时,Visual Studio自动生成的服务代理将自动在启动服务调用的线程上分派已完成的回调事件.

在您的情况下,这意味着xClient_Retrieve_File_Completed确实在您的UI线程上执行.

更新:
实际上很难将文件请求和文件处理全部放在一个线程上,然后在所有请求和处理完成后更新UI,因为在完成对服务的请求时必须保持线程处于活动状态.无法保证服务请求将按照发送顺序完成,因此您必须跟踪已完成请求的数量,并且只有在所有请求完成后,您才能通知UI并结束线程.

对我来说,这听起来像一个脆弱而复杂的设计,不幸的是,你可能用于这种设计的CountDownEvent在Silverlight中不存在.

或者,您可以考虑更改服务和ProcessFile的设计,以便您可以同时请求和处理所有文件,这样您只需要发出一个服务请求(除非您通过网络向和从数据库发送大量数据)服务).然后,您可以生成BackgroundWorker(as suggested by Matthew Paul Keelan in his answer)以一次处理所有文件.您的代码看起来与此类似:

// 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();
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐