2010-09-20 125 views
1

我經常使用RIA WCF服務,並在幾個ViewModel中注入相同的上下文。我的問題是,如你所知,RIA服務的上下文不是線程安全的。線程安全,Silverlight

所以我的解決方案是「自制的」進行同步。我使用的是後臺工作者,並使用PostSharp,我在方法和瞧上應用我的屬性 [UniqueThread(「Data」)]。

我是否讓事情變得複雜?有更簡單的解決方案嗎?

最好的問候,
文森特BOUZON

回答

0

這當然顯得過於複雜,除非你已經做了很多其他工作,迫使你的ViewModels是單獨的線程上運行。當然,默認情況下,你編寫的任何東西都會在主前臺線程上運行,並且不需要參與你描述的那些複雜的東西。或者,您的視圖模型是否在單獨的(後臺)線程上運行?

+0

它並不複雜。但是例如,爲RIA服務創建的實體不應該在UI線程中完成,它需要很長的時間纔會凍結UI。因此,所有涉及在後臺線程上運行的RIA上下文和我的UI更加流暢。 – 2010-09-20 23:10:23

+0

我在我的項目中完成了類似的東西,我使用ThreadPool.QueueUserWorkItem()將所有WCF通信移動到後臺線程。它不會讓事情變得更快,因爲它使UI看起來更順暢。但接下來我基本上做了HiTech Magic的答案,即在必要時使用Dispatcher.BeginInvoke()將數據封送回UI線程。但是我沒有使用RIA服務,所以我不必擔心同步對其上下文的訪問。一個簡單的鎖對象(例如,「lock(myRiaContext){}」)會給你你需要的同步嗎? – 2010-09-21 15:37:28

+0

是的,當然,我也使用PostSharp注入的鎖。 – 2010-09-27 08:07:32

4

在我們的例子中,我們添加了一個OnUiThread方法到我們的BaseViewModel(它也提供INotifypropertyChanged處理程序和一些其他方便的util方法)。

每當我們需要以確保在UI線程上完成操作時,我們使用lambda表達式(或回調函數)調用OnUiThread來完成這項工作。

protected delegate void OnUiThreadDelegate(); 

protected void OnUiThread(OnUiThreadDelegate onUiThreadDelegate) 
{ 
    if (Deployment.Current.Dispatcher.CheckAccess()) 
    { 
     onUiThreadDelegate(); 
    } 
    else 
    { 
     Deployment.Current.Dispatcher.BeginInvoke(onUiThreadDelegate); 
    } 
} 

通話的一個例子可能看起來像:

this.OnUiThread(() => 
    { 
     this.ViewModelList = resultList; 
    });