我正在尝试解决SL性能问题。 直到现在我有WCF调用由InvokeAsync执行。 现在,我将其更改为使用BackgroundWorker。 性能大大提高。在Silverlight UI线程中,在执行InvokeAsync时会发生什么?
什么会导致这种情况? InvokeAsync究竟做了什么影响UI线程?它打开另一个UI线程?
谢谢
我正在尝试解决SL性能问题。 直到现在我有WCF调用由InvokeAsync执行。 现在,我将其更改为使用BackgroundWorker。 性能大大提高。在Silverlight UI线程中,在执行InvokeAsync时会发生什么?
什么会导致这种情况? InvokeAsync究竟做了什么影响UI线程?它打开另一个UI线程?
谢谢
它归结为同步上下文。一个线程可能与SynchronizationContext
相关联,如DispatcherSynchronizationContext
(这是UI线程的上下文,并且只包含这一个线程)。 WCF将在它开始的同一个同步上下文中完成一个操作,如果没有与该线程关联的同步上下文,它将使用线程池中的任何线程。
因此,如果您有几个优秀的异步操作都从UI线程调用,那么所有这些操作都需要在UI线程中运行它们的完成代码。如果其中一些完成代码同时完成,则代码将不得不排队等待分发到单个UI线程中。
而当您调用后台工作程序中的异步操作时,它将从线程池运行到线程中,并且没有特殊的同步上下文。当这些操作完成其完成代码时,可以在池中的任何可用线程上运行(其中有几个)。所以几乎同时完成可以在不同的线程上并行运行。
在WPF和Silverlight中,我推荐使用SynchronazationContext来保存主线程,所有其他线程将使用SynchronazationContext的这个实例来访问主线程(UI)。你以这种方式使用它(注:我生成这样做,所有其他方法将访问此方法来更新UI的方法):
SynchronazationContext ctx = null;
void DoSomething()
{
ctx = SynchronazationContext.Current;
//Some algorithm here
this.UpdatePic("Success !");
}
void ThreadProc()
{
SendOrPostCallback callBack = new SendOrPostCallback(UpdatePic);
ctx.Post(callBack, String.Format("Put here the pic path");
}
void UpdatePic(string _text)
{
//This method run under the main method
}
在.NET 5.0,你可以调用纪念这个复杂的功能方法async并在调用同步方法时写入'await' - 将同步方法设置为异步方法并使用主线程更新UI。