2013-06-22 100 views
2

我的代碼塊:任務<T>凍結UI線程

Dispatcher.BeginInvoke(() => { 
      var Users = GetUsers().Result; 
      // proceed... 
     } 

private Task<List<User>> GetUsers() 
{ 
    var tcs = new TaskCompletionSource<List<User>>(); 
    wbclient.DownloadStringCompleted += (o, e) => { 
       if (e.Error == null) 
        tcs.SetResult(JsonConvert.DeserializeObject<List<User>>(e.Result)); 
       else 
        tcs.TrySetException(e.Error); 
       }; 
    wbclient.DownloadStringAsync(someUri); 
    return tcs.Task; 
} 

我想,然後再繼續讓所有的用戶。所以我在調度員中調用GetUser方法。我只想等到DownloadStringCompleted事件發生,然後返回。但通過上面的代碼,UI會凍結。任何幫助表示讚賞。

注:

我使用windows-phone 7,不支持asyncawait

+1

不,不。沒有。 Dispatcher **強制**它在UI線程中運行。 –

+0

@newStackExchangeInstance仍然UI凍結! –

+0

@AshokDamani:是的,因爲你正在使用'任務 .Result'。閱讀該財產的文檔。 –

回答

3

您應該使用一個延續和刪除Dispatcher.BeginInvoke呼叫和.Result呼叫你的主線程是阻止:

GetUsers().ContinueWith(t => 
{ 
    List<User> users = t.Result; 
    this.TextBlock1.Text = "Complete"; 
}, TaskScheduler.FromCurrentSynchronizationContext()); 

注意如何我已經使用在TaskScheduler.FromCurrentSynchronizationContext()通話繼續確保這個延續在主UI線程上編組。

+2

請注意,這假定這個代碼已經在UI線程上執行。 (否則,當前同步上下文不會是正確的。) –

+0

'GetUsers()ContinueWith(T => 。{ 列表用戶= t.Result; MessageBox.Show( 「完成」);} , TaskScheduler.FromCurrentSynchronizationContext());' 好的UI不會凍結。 但messageBox不顯示呢? –

+0

代碼執行是否進入延續?當你在其中放置斷點時會發生什麼?請求是否成功?你能夠獲得用戶嗎? –

1

您可以在Windows Phone 7上使用異步等待,您只需將this nuget packet安裝到解決方案中的所有項目中即可。即使某些項目與Windows Phone 8共享,或者某些項目是可移植的類庫,也可以很好地工作。很有幫助。

所以,你應該那麼可以使用:var Users = await GetUsers();

順便說一句,你總是可以使用HttpClient的,而不是Web客戶端的:http://nuget.org/packages/Microsoft.Net.Http/2.1.10