C#:如果一个线程失败,则终止其他线程

标签 c# multithreading asp.net-web-api task

如果其中一个线程失败,是否有任何方法可以停止其他并发线程的执行?我正在开发一个 ASP.NET MVC 网站,该网站将大量使用 API 调用。我没有按顺序发送过多的 API 请求,而是创建了线程,每个线程使用一个 API 调用。如果任何线程失败,我想杀死其他线程。我怎样才能做到这一点?我使用了 Task.WaitAll 但它允许所有其他线程执行,即使一个线程失败也是如此。请帮忙。

更新: 为了模拟实时场景,我创建了一个控制台应用程序。请引用下面的代码。我想让第五个线程失败。第五个线程失败后,我希望所有其他正在运行的线程停止。

public class Program
{
        static int[] delays = { 3, 2, 10, 4, 5, 6, 7, 8, 9, 1 };
        static int[] ids = new int[10];
        static Task[] tasks = null;
        static CancellationTokenSource tokenSource = new CancellationTokenSource();
        static IList<int> threadsExecuted = new List<int>();

        static void Main(string[] args)
        {
            ids = Enumerable.Range(1, 10).ToArray();

            try
            {
                tasks = ids.Select(id => MyTaks(id)).ToArray();
                Task.WaitAll(tasks);
            }
            catch (Exception exception)
            {
                Console.WriteLine("Exception in Main::\nMessage: " + exception.Message +
                    "StackTrace: " + exception.StackTrace +
                    "InnerException: " + exception.InnerException);
            }

            Console.WriteLine("\n\nThreads executed: " + string.Join(", ", threadsExecuted.OrderBy(id => id).ToArray()));

            Console.WriteLine("\n\n\nExit..");

            Console.Read();
        }

        private static async Task MyTaks(int id)
        {
            var delay = delays[id - 1] * 1000;

            Console.WriteLine("Thread id #" + id + " started with delay " + delay + " seconds.");

            CancellationToken cToken = tokenSource.Token;

            Task task = new Task(() =>
            {
                Thread.Sleep(delay);

                if (id == 5) //Fail
                {
                    Console.WriteLine("Cancelling..");

                    throw new Exception("Thread id #" + id + " failed.");
                }
            }, cToken);

            task.Start();

            await task;

            Console.WriteLine("Thread id #" + id + " executed.");

            threadsExecuted.Add(id);
        }

最佳答案

Instead of sending too many API requests in sequential fashion, I am creating threads, each thread consuming one API call.

这种方法几乎会破坏您服务器的任何可扩展性。您应该使用异步并发(多个操作),而不是并行并发(多线程)。您的 API 代码将使用 HttpClient.GetAsync 并传递 CancellationToken

因此,您的测试代码将如下所示:

static void Main(string[] args)
{
  ids = Enumerable.Range(1, 10).ToArray();

  try
  {
    tasks = ids.Select(id => MyTaks(id)).ToArray();
    Task.WaitAll(tasks);
  }
  catch (Exception exception)
  {
    Console.WriteLine("Exception in Main::\nMessage: " + exception.Message +
                "StackTrace: " + exception.StackTrace +
                "InnerException: " + exception.InnerException);
  }

  lock (threadsExecuted)
    Console.WriteLine("\n\nThreads executed: " + string.Join(", ", threadsExecuted.OrderBy(id => id).ToArray()));

  Console.WriteLine("\n\n\nExit..");

  Console.Read();
}

private static async Task MyTaks(int id)
{
  var delay = delays[id - 1] * 1000;

  Console.WriteLine("Task id #" + id + " started with delay " + delay + " seconds.");

  CancellationToken cToken = tokenSource.Token;

  // Production code would use `await httpClient.GetAsync(url, token)` here.
  await Task.Delay(delay, cToken);

  if (id == 5) //Fail
  {
    Console.WriteLine("Cancelling..");
    tokenSource.Cancel();
    throw new Exception("Thread id #" + id + " failed.");
  }

  Console.WriteLine("Thread id #" + id + " executed.");
  lock (threadsExecuted)
    threadsExecuted.Add(id);
}

关于C#:如果一个线程失败,则终止其他线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38012732/

相关文章:

c# - 如何去除 ListBox 的模糊效果?

c# - C# 和 SQL 新手 - 为什么我的 .AddWithValue 不起作用?

c# - Prism.Autofac.Forms 实现

multithreading - Delphi线程: CriticalSection not being "Release' d"when using Synchronize inside its method

asp.net - 如何从 ASP.NET Web API 方法内部找到声明的内容?

angularjs - 使用 angualrjs 和带有 webapi 的 abp 样板上传文件

c# - 如何在本地/内部托管 Azure 辅助角色?

multithreading - 为什么本地创建的结构不能发送到另一个线程?

java - 实现 java FixTreadPool 状态监听器

c# - 在运行时禁用 OData V4 元数据和 Controller