c#中的多线程异常处理

本文介绍了C#中处理多线程异常的方法,包括:1. 对于Thread操作,异常应在每个线程内部捕获;2. 异步函数如WebClient的UploadStringAsync,异常会在完成事件中传递;3. Task的异常处理,可以通过Wait或设置OnlyOnFaulted的继续任务来捕获;4. C# 5.0中async、await的关键字处理异常,参考链接提供详细信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.对于Thread操作的异常处理

public static void Main()
{
  try
  {
    new Thread (Go).Start();
  }
  catch (Exception ex)
  {
    // We'll never get here!
    Console.WriteLine ("Exception!");
  }
}
static void Go() { throw null; }   // Throws a NullReferenceException


在go函数里抛出的异常时不会被主线程的try,catch捕捉的,各个线程应该有自己的try,catch去处理线程异常。

正确写法:

public static void Main()
{
   new Thread (Go).Start();
}
static void Go()
{
  try
  {
    ...
    throw null;    // The NullReferenceException will get caught below
    ...
  }
  catch (Exception ex)
  {
    Typically log the exception, and/or signal another thread
    that we've come unstuck
    ...
  }

}


2. 异步函数的异常处理

比如 WebClient中的 UploadStringAsync,它的异常会在UploadStringCompleted的参数error里

        static void Main(string[] args)
        {
            WebClient webClient = new WebClient();
            webClient.UploadStringCompleted += new UploadStringCompletedEventHandler((sender, e) =>
                {
                    if (e.Error != null)
                    {
                        Console.WriteLine(e.Error.Message);


                    }
                });
            webClient.UploadStringAsync(new Uri("http://www.baidu.com"), "1111");
            Console.ReadKey();
        }


3 Task的异常处理

把try包含task.wait()函数,就能捕捉task的异常

// Start a Task that throws a NullReferenceException:
Task task = Task.Run (() => { throw null; });
try
{
  task.Wait();
}
catch (AggregateException aex)
{
  if (aex.InnerException is NullReferenceException)
    Console.WriteLine ("Null!");
  else
    throw;
}

或者 在continue函数里处理TaskContinuationOptions.OnlyOnFaulted的状态

       // create the task
            Task<List<int>> taskWithFactoryAndState =
                Task.Factory.StartNew<List<int>>((stateObj) =>
                {
                    List<int> ints = new List<int>();
                    for (int i = 0; i < (int)stateObj; i++)
                    {
                        ints.Add(i);
                        if (i > 100)
                        {
                            InvalidOperationException ex =
                                new InvalidOperationException("oh no its > 100");
                            ex.Source = "taskWithFactoryAndState";
                            throw ex;
                        }
                    }
                    return ints;
                }, 2000);


            //and setup a continuation for it only on when faulted
            taskWithFactoryAndState.ContinueWith((ant) =>
                {
                    AggregateException aggEx = ant.Exception;
                    Console.WriteLine("OOOOPS : The Task exited with Exception(s)");


                    foreach (Exception ex in aggEx.InnerExceptions)
                    {
                        Console.WriteLine(string.Format("Caught exception '{0}'",
                            ex.Message));
                    }
                }, TaskContinuationOptions.OnlyOnFaulted);

            //and setup a continuation for it only on ran to completion
            taskWithFactoryAndState.ContinueWith((ant) =>
            {
                List<int> result = ant.Result;
                foreach (int resultValue in result)
                {
                    Console.WriteLine("Task produced {0}", resultValue);
                }
            }, TaskContinuationOptions.OnlyOnRanToCompletion);
            Console.ReadLine();



4 c# 5.0 中的async ,await 异常捕捉

static async Task ThrowAfter(int timeout, Exception ex)
{
    await Task.Delay(timeout);
    throw ex;
}

static async Task MissHandling()
{
    var t1 = ThrowAfter(1000, new NotSupportedException("Error 1"));

    try
    {
        await t1;
    }
    catch (NotSupportedException ex)
    {
       Console.WriteLine(ex.Message);
    }
}

详细参考:http://blog.zhaojie.me/2012/04/exception-handling-in-csharp-async-await-1.html




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值