首页 > 解决方案 > 当等待的一部分具有 ConfigureAwait false 时使用 MessageBox

问题描述

阅读斯蒂芬克利里不阻塞异步代码我写了这样的东西

public static async Task<JObject> GetJsonAsync(Uri uri)
{
   using (var client = new HttpClient())
   {
      var jsonString = await client.GetStringAsync(uri).ConfigureAwait(false);  
      return JObject.Parse(jsonString);
   }
}

public async void Button1_Click(...)
{
    var json = await GetJsonAsync(...);
    textBox1.Text=json;
}

到目前为止一切顺利,我知道该方法将在返回ConfigureAwait后继续在不同的上下文中运行。GetStringAsync但是如果我想使用像这样的东西MessageBox(这是 UI)呢?

public static async Task<JObject> GetJsonAsync(Uri uri)
{
   if(someValue<MAXVALUE)
   {
      using (var client = new HttpClient())
      {
         //var jsonString = await client.GetStringAsync(uri);  //starts the REST request
         var jsonString = await client.GetStringAsync(uri).ConfigureAwait(false);    
         return JObject.Parse(jsonString);
      }
   }
   else
   {
      MessageBox.Show("The parameter someValue is too big!");
   }
}

我可以这样做吗?

更复杂的是,这个怎么样?

public static async Task<JObject> GetJsonAsync(Uri uri)
{
   if(someValue<MAXVALUE)
   {
      try{
         using (var client = new HttpClient())
         {
            //var jsonString = await client.GetStringAsync(uri);  //starts the REST request
            var jsonString = await client.GetStringAsync(uri).ConfigureAwait(false);    
            return JObject.Parse(jsonString);
         }
      }
      catch(Exception ex)
      {
         MessageBox.Show("An Exception was raised!");
      }
   }
   else
   {
      MessageBox.Show("The parameter someValue is too big!");
   }
}

我可以这样做吗?

现在,我在想也许所有的消息框都应该在 GetJsonAync 之外调用作为好的设计,但我的问题是上述事情可以完成吗?

标签: c#async-await

解决方案


我可以这样做吗?[使用消息框]

是的,但主要是因为它与异步/等待或线程无关。
MessageBox.Show()很特别,它是一个静态方法,并被记录为线程安全的。

您可以随时从任何线程显示 MessageBox。

所以也许这是一个错误的例子,但你确实在标题中有 MessageBox。

public static async Task<JObject> GetJsonAsync(Uri uri)
{
   try{
     ...  // old context
     ... await client.GetStringAsync(uri).ConfigureAwait(false);
     ...  // new context
   }
   catch
   {
      // this might bomb
      someLabel.Text = "An Exception was raised!";
   }
}

在此示例中,可能存在 catch 在旧上下文中运行的代码路径和在新上下文中运行的其他路径。

底线是:您不知道并且应该假设最坏的情况。


推荐阅读