c#中的多线程异常 (转载)

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

public static void Main()
{
    try
    {
        Thread th = new Thread(DoWork);
        th.Start();
    }
    catch (Exception ex)
    {
        // Non-reachable code
        Console.WriteLine("Exception!");
    }
}

static void DoWork()
{
    ……
    throw null;  // Throws a NullReferenceException 
}

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

public static void Main()
{
    Thread th = new Thread(DoWork);
    th.Start();
}

static void DoWork()
{
    try
    {
        ……
        throw null;    // The NullReferenceException will be 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的异常

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的状态

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);
    }
}

原文链接

猜你喜欢

转载自www.cnblogs.com/OpenCoder/p/10332698.html