2015-06-24 21 views
0

我正在試驗MSDN示例。我遇到了以下問題。從按鈕單擊事件處理程序運行async代碼塊時,使用async模式,它可以正常工作(button1_Click)。但是對於button2_Click,控制不超出TaskObj.Result。什麼可能是相同的原因?控件在非異步塊中的Task.Result之後不產生

private async void button1_Click(object sender, EventArgs e)//this works fine 
    { 
     Task<int> TaskObj = AccessTheWebAsync(); 
     string a ="I came here.."; 

     int y = await TaskObj; 

     string a1 = "I came here also.."; 
    } 

    private void button2_Click(object sender, EventArgs e)//this is not working 
    { 
     Task<int> TaskObj = AccessTheWebAsync(); 
     string a = "I came here..";//control yielded here 
     int y = TaskObj.Result;//something happened here 
     string a1 = "Why I couldn't come here?";//why control is not reaching here? 
    } 


    async Task<int> AccessTheWebAsync() 
    { 
     HttpClient client = new HttpClient(); 
     Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");   
     DoIndependentWork(); 
     string urlContents = await getStringTask; 
     return urlContents.Length; 
    } 

    private void DoIndependentWork() 
    { 
     IList<Int32>intK = Enumerable.Range(1, 100000000).ToList(); 
     foreach (int x in intK) 
     { 
      int y = x * 2; 
     } 
    } 

回答

4

可能是什麼原因相同?

區別是一個死鎖,而其他不。當你await,你異步等待通過讓控制回到調用方法。當您使用Task.Result時,您會同時阻止通話。這導致了僵局。

爲什麼?因爲這裏涉及到了一個叫做「同步上下文」的東西,它負責執行你的延續(在第一個await之後的所有代碼)在之前使用的相同上下文中的一些魔力,在你的情況下它是UI線程。由於您與Task.Result同步阻止,繼續無法將自己封送回UI線程,因爲它正在等待.Result本身。

相反,使用await與以前的按鈕點擊:

private async void button2_Click(object sender, EventArgs e)//this is not working 
{ 
    Task<int> TaskObj = AccessTheWebAsync(); 
    string a = "I came here..";//control yielded here 
    int y = await TaskObj; 
} 
相關問題