1. 程式人生 > >c#中的多執行緒異常處理

c#中的多執行緒異常處理

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