【问题标题】:ThreadAbortException with await带有等待的 ThreadAbortException
【发布时间】:2014-03-30 22:42:22
【问题描述】:

我正面临一个奇怪的错误。 我有大约 100 个长时间运行的任务,我想同时运行其中的 10 个。

我在这里找到了与我的需求非常相似的东西:http://msdn.microsoft.com/en-us/library/hh873173%28v=vs.110%29.aspx 在节流部分。

这里是简化后的C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            Test();
        }

        public static async void Test()
        {
            var range = Enumerable.Range(1, 100).ToList();

            const int CONCURRENCY_LEVEL = 10;
            int nextIndex = 0;
            var matrixTasks = new List<Task>();

            while (nextIndex < CONCURRENCY_LEVEL && nextIndex < range.Count())
            {
                int index = nextIndex;
                matrixTasks.Add(Task.Factory.StartNew(() => ComputePieceOfMatrix()));
                nextIndex++;
            }

            while (matrixTasks.Count > 0)
            {
                try
                {
                    var imageTask = await Task.WhenAny(matrixTasks);
                    matrixTasks.Remove(imageTask);
                }
                catch (Exception e)
                {
                    Console.Write(1);
                    throw;
                }

                if (nextIndex < range.Count())
                {
                    int index = nextIndex;
                    matrixTasks.Add(Task.Factory.StartNew(() => ComputePieceOfMatrix()));
                    nextIndex++;
                }
            }

            await Task.WhenAll(matrixTasks); 
        }

        private static void ComputePieceOfMatrix()
        {
            try
            {
                for (int j = 0; j < 10000000000; j++) ;
            }
            catch (Exception e)
            {
                Console.Write(2);
                throw;
            }
        }
    }
}

从单元测试运行它时,ComputePieceOfMatrix 中会出现 ThreadAbortException。

你有什么想法吗?

编辑:

根据评论,我试过这个:

static void Main(string[] args)
{
    Run();
}

private static async void Run()
{
    await Test();
}

public static async Task Test()
{
    var range = Enumerable.Range(1, 100).ToList();

但是完全一样。

【问题讨论】:

  • 等等,什么? async void?我想你的意思是async Task
  • Resharper 告诉我,如果我不使用它,返回一个任务是没有用的。我会尝试使用它。
  • 我猜你的主线程在Test 完成之前就退出了,而现有线程在应用程序退出之前就被中止了。
  • 我已经编辑了我的问题。这不起作用...谢谢!

标签: c# multithreading exception task async-await


【解决方案1】:

1.您的代码导致异常

try
{
    for (int j = 0; j < 10000000000; j++) ;
}
catch (Exception e)
{
    Console.Write(2);
    throw;
}

只是一个简单的溢出异常,因为 10000000000 - 很长并且 j 计数器 int。

2.您的主线程在子线程运行完成之前退出。您很可能会收到 ThreadAbortException,因为线程已被运行时关闭

3.await Test() - 正确调用 Test(),然后等待 Task.WhenAny 也无需等待

【讨论】:

  • 哇...是的,您的测试代码是正确的。但在我的真实代码中,原因不一样……我实际上是在调用网络服务。现在我必须找到一个像我真正的代码崩溃一样崩溃的小代码,但没有像这样的愚蠢错误......谢谢!
  • 是的,var imageTask = await Task.WhenAny(matrixTasks); await 在那里不正确。只是这里也没有等待,因为您的执行流程将被破坏。
  • 它必须被打破,否则我将有10多个任务同时运行。
【解决方案2】:

我会将您的 Test 从 void 更改为 Task 返回类型,并在 main 方法中代替 Test();

Task t = Test();
t.Wait();

【讨论】:

    【解决方案3】:

    Test() 的返回类型更改为Task,然后等待Task 在程序结束之前完成。

    static void Main(string[] args)
    {
        Test().Wait();
    }
    
    public static async Task Test()
    {
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-08
      • 1970-01-01
      • 2017-03-13
      • 1970-01-01
      • 2019-10-23
      • 2014-01-25
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多