控件在任务之后未屈服.导致非异步块

本文关键字:异步 屈服 任务 之后 控件 | 更新日期: 2023-09-27 17:59:13

我正在试用MSDN示例。我遇到了以下问题。当使用async模式从按钮单击事件处理程序运行async代码块时,它工作正常(button1_Click)。但对于button2_Click,控制不会超出TaskObj.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;
      }
    }

控件在任务之后未屈服.导致非异步块

同样的原因可能是什么?

区别在于一个死锁,而另一个没有。await时,通过将控制权交还给调用方法,异步等待。当您使用Task.Result时,您会同步阻止呼叫。这导致了僵局。

为什么?因为这里涉及到一种叫做"同步上下文"的东西,它负责在它之前使用的相同上下文中执行延续(第一个await之后的所有代码)的一些魔力,在您的情况下,这就是UI线程。因为您与Task.Result同步进行了阻塞,所以continuation无法将自己封送回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;
}