c#indefinte任务继续执行异常

时间:2017-11-20 09:08:01

标签: c# multithreading async-await task-parallel-library

我已经开始在TPL中探索.NET来实现一个Windows服务,该服务将在每次成功执行后并行运行多个独立方法并延迟一些延迟,以下是我提出的粗略控制台应用程序看了各种例子之后:

class Program
{
    static void Main(string[] args)
    {
        CancellationTokenSource _ct1 = new CancellationTokenSource();
        CancellationTokenSource _ct2 = new CancellationTokenSource();
        int count = 0;
        var task1 = new Task(async () =>
        {
            try
            {
                while (true)
                {
                    DoWork();
                    await Task.Delay(2000, _ct1.Token);
                    count++;
                    if (count >= 5)
                    {
                        throw new NotImplementedException();
                    }
                }
            }
            catch (TaskCanceledException ex)
            {
                //Log cancellation and do not continue execution
                Console.WriteLine("DoWork cancelled: " + ex.Message);
            }
            catch (Exception ex)
            {
                //Log error and continue with execution
                Console.WriteLine("Error occurred at DoWork");
            }
        }, _ct1.Token, TaskCreationOptions.LongRunning);

        var task2 = new Task(async () =>
        {
            try
            {
                while (true)
                {
                    DoWork2();
                    await Task.Delay(2000, _ct2.Token);
                    count++;
                    if (count >= 5)
                    {
                        _ct2.Cancel();
                    }
                }
            }
            catch (TaskCanceledException ex)
            {
                //Log cancellation and do not continue execution
                Console.WriteLine("DoWork2 cancelled: " + ex.Message);
            }
            catch (Exception ex)
            {
                //Log error and continue with execution
                Console.WriteLine("Error occurred at DoWork");
            }
        }, _ct2.Token, TaskCreationOptions.LongRunning);

        task1.Start();
        task2.Start();
        Console.ReadKey();
    }

    public static void DoWork()
    {
        Console.WriteLine("Doing something...");
    }

    public static void DoWork2()
    {
        Console.WriteLine("Doing something else...");
    }
}

在上面的代码中,当任务执行期间发生任何异常时,我需要记录错误然后继续执行任务,现在如果有异常,任务就会停止执行。我的问题:

  1. 如何正确处理异常,以便任务执行不会停止?
  2. 当我在DoWork()方法添加调试器断点时,DoWork2()不会运行,这意味着任务不在单独的线程上并行运行并在单个线程上运行并相互阻塞。如何确保Tasks在不同的线程上相互独立运行?
  3. PS:上面的代码是一个简单的控制台应用程序,只是为了理解TPL的工作原理,所以如果有明显的设计问题请忽略。

1 个答案:

答案 0 :(得分:0)

我相信你可以做的最简单的方法是让你的task1在异常之后运行,如下所示:

var task1 = new Task(async () =>
{
    while (true)
    {
        try
        {
            DoWork();
            await Task.Delay(2000, _ct1.Token);
            count++;
            if (count >= 5)
            {
                throw new NotImplementedException();
            }
        }
        catch (TaskCanceledException ex)
        {
            //Log cancellation and do not continue execution
            Console.WriteLine("DoWork cancelled: " + ex.Message);
            break;
        }
        catch (Exception ex)
        {
            //Log error and continue with execution
            Console.WriteLine("Error occurred at DoWork");
            count = 0;  //  without this you'll have exception thrown on each of further iterations
        }
    }
}, _ct1.Token, TaskCreationOptions.LongRunning);

意味着try ... catch在循环中移动。

当你没有看到task2正在运行时,请注意@ pull420评论