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