你的位置:首页 > 软件开发 > ASP.net > 异步编程异常和死锁处理

异步编程异常和死锁处理

发布时间:2015-08-07 14:00:12
在.NET异步编程中,通常使用async和await这对黄金搭档,返回类型使用Task或Task<T>。在方法前面加async表示这个方法运行异步,在方法内使用await表示执行一个异步等待。 下面是一个简单例子: static void Mai ...

 

.NET异步编程中,通常使用async和await这对黄金搭档,返回类型使用Task或Task<T>。在方法前面加async表示这个方法运行异步,在方法内使用await表示执行一个异步等待。

 

下面是一个简单例子:

 

    static void Main(get='_blank'>string[] args)
    {
      Doth();
      Console.ReadKey();
    }
    static async Task Doth()
    {
      int i = 2;
      await Task.Delay(TimeSpan.FromSeconds(2));
      i += 2;
      await Task.Delay(TimeSpan.FromSeconds(2));
      Console.WriteLine(i);
    }

 

当执行DoSth方法,第一个await执行一个异步等待,当执行完成,就继续执行下面的代码。在async修饰的方法内部,一个await就是一个异步等待,可以包含多个await, 每一个await执行完毕才会执行它后面的代码,也就是说在DoSth内部是同步的。

 

各个await在哪个线程中运行呢?

 

默认情况下是在当前线程中运行,不过.NET提供了ConfigureAwait方法,用来设置await在哪个线程中运行。

 

    static async Task Doth()
    {
      int i = 2;
      await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
      i += 2;
      await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
      Console.WriteLine(i);
    }

 

以上,当第一个await运行在控制台项目所在的线程中,第二个await将在线程池上运行。

 

我们无法保证每个await不会抛出异常,通常按如下的方式捕获异常。

 

async Task DosthAsync()
{
  try
  {
    await PossibleExceptionAsync();
  }
  catch(NotSuppotedException ex)
  {
    LogException(ex);
    throw;
  }
}

 

由于抛出的异常会放在Task对象中,所以也可以这么写:

 

async Task DosthAsync()
{
  Task task = PossibleExceptionAsync();
  try
  {
    await task;
  }
  cach(NotSupportedException ex)
  {
    LogException(ex);
    throw;
  }
}

 

异步编程也会出现死锁。

 

async Task DoSthSync()
{
  await Task.Delay(TimeSpan.FromSeconds(1));
}
void FirstThing()
{
  Task tak = DoSthSync();
  task.Wait();
}

 

以上,如果调用FirstThing方法就会出现死锁的情况。

 

→执行FirstThing方法

原标题:异步编程异常和死锁处理

关键词:异步

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。