我正在嘗試解決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。