使用非UI线程从silverlight客户端调用WCF服务

时间:2010-11-03 14:16:51

标签: wpf silverlight

我有一个非常简单的场景:
我的silverlight应用程序中有一个异步WCF服务调用 我想在一个单独的线程(或类似的)上执行它们,因为它们冻结了我的UI 所有服务调用都是为了更新ViewModel,从而更新页面上的/ UI控件,因此需要从运行服务调用的线程中找到一种方法,而不需要熟悉的跨线程异常。
有什么建议?

非常感谢。

3 个答案:

答案 0 :(得分:3)

在与WCF团队的人们交谈时,这是我对它如何运作的理解。如果您只是从后台线程进行调用,它将无法工作,因为WCF子系统会将调用编组回到您最初打开连接的线程(通常是UI线程)。因此,您需要做的是创建一个工作线程,然后从该线程显式打开连接。然后,无论何时进行调用,它都会被封送回该线程。当然,一旦你收到了回调并完成了处理(在后台线程上),那么请确保使用Dispatcher.BeginInvoke()将任何UI更改编组回UI线程。

答案 1 :(得分:0)

您可以使用BackgroundWorker,也可以将客户端代理支持Asynchronous Pattern

确保将UI更新分派给正确的线程,如下所述: http://russelleast.wordpress.com/2010/02/27/using-wcf-async-pattern-with-silverlight-3/

答案 2 :(得分:0)

Dispatcher.BeginInvoke是最佳解决方案。

服务代理的部分定义:

public void GetItemById(int id, Action<ItemModel> callback)
{
    AsyncCallback onCompleted = ar => 
        Deployment.Current.Dispatcher.BeginInvoke(() => 
            callback(this.Channel.EndGetItemById(ar)));
    this.Channel.BeginGetItemById(id, onCompleted, null);
}

从MVVM调用:

var proxy = new MyServiceProxy();
proxy.GetItemById(5, item => this.Item = item);