2008-12-09 49 views
2

我在Silverlight應用程序中使用ADO.NET數據服務,並且由於silverlight庫不支持IQueryable上的ToList()調用,我認爲可以創建擴展方法稱爲SilverlightToList()。因此,在這個方法中,我號召我的背景下,BeginExecute方法如下所示:在Silverlight中同步ADO.NET數據服務調用

  var result = context.BeginExecute<T>(currentRequestUri,null,context); 
      result.AsyncWaitHandle.WaitOne(); 
      return context.EndExecute<T>(result).ToList(); 

的問題是,當我調用了WaitOne()方法,這會導致死鎖。這是Silverlight中ADO.NET數據服務的限制嗎?有沒有解決這個問題的方法?

+0

好問題,Silverlight中的一個常見問題 – 2009-10-08 08:28:46

回答

1

因爲我已經發現this post在MSDN論壇裏面說,任何managed-> UnManaged->管理編組發生在UI線程這解釋了爲什麼的WaitOne方法調用掛在...

1

Silverlight可能不會同步任何東西,因爲它打算在瀏覽器中運行,並且它只能有一個線程來玩 - 它必須共享它。唯一可用於主機的線程是瀏覽器提供的線程。

+0

是不是隻有一個線程使它更有可能同步調用項目? – ChrisHDog 2008-12-09 02:55:07

+0

不,這意味着它不需要,因爲它會凍結瀏覽器中所有其他標籤上的所有內容。 – dkretz 2008-12-09 03:11:40

1

所有服務電話在Silverlight中必須是異步的。所以,你必須定義一個回調來得到的結果 - 這樣的:

context.BeginExecute<T>(currentRequestUri, resultCallback, context); 

private void resultCallback(IAsyncResult asyncResult) 
{ 
    DataServiceContext context = asyncResult.AsyncState as DataServiceContext; 
    var result = context.EndExecute<T>(asyncResult); 
    // Do whatever you need with the result here 
} 

下面是在MSDN一個很好的參考:http://msdn.microsoft.com/en-us/library/cc838191(VS.95).aspx

3

我已成功地擊敗(:P)在Silverlight異步怪物一樣所以:

var ctx = new ModelEntities(new Uri("http://localhost:2115/Data.svc")); 

ManualResetEvent m1 = new ManualResetEvent(false); 
ManualResetEvent m2 = new ManualResetEvent(false); 

var q1 = (DataServiceQuery<Department>)(from e in ctx.Department select e); 
var q2 = (DataServiceQuery<Person>)(from e in ctx.Person select e); 

Department[] r1 = null; 
Person[] r2 = null; 

q1.BeginExecute(r => 
{ 
    try { r1 = q1.EndExecute(r).ToArray(); } 
    finally { m1.Set(); } 
}, null); 
q2.BeginExecute(r => 
{ 
    try { r2 = q2.EndExecute(r).ToArray(); } 
    finally { m2.Set(); } 
}, null); 

ThreadPool.QueueUserWorkItem((o) => 
{ 
    WaitHandle.WaitAll(new WaitHandle[] { m1, m2 }); 
    // do your thing.. 
}); 

基本的ideea是派生一個服務器線程(最後一個塊),它將引用等待對象。請勿將WaitAll調用放入調用方法/線程中,因爲這會導致本網站或其他站點中前面提到的其他問題的死鎖。

發生死鎖是因爲線程直到方法結束並且方法沒有結束纔會啓動,因爲WaitAll調用等待子線程結束。

不是在我上面的情況,但因爲WaitAll是在另一個線程上。

PS:而不是//做你的事情行代碼使用r1和r2捕獲的引用將保存數據或null如果結果失敗。