【问题标题】:Parallel.For Loop with Thread-Local Variables带有线程局部变量的 Parallel.For 循环
【发布时间】:2014-02-24 20:11:46
【问题描述】:

我有一个C# ASP.NET MVC 项目。
我基本上是在运行模拟(可以选择取消)并整理结果。
我需要使用multi-threading,因为我一次可以运行一百万个或更多模拟。
我的代码是这样的:

public class MyClass
{
    private ConcurrentBag<StuffResult> StuffResults { get; set; }
    private bool CancellationRequested { get; set; }

    public void DoAlotOfStuff(int numberOfStuffToDo)
    {
        var cancellationTokenSource = new CancellationTokenSource();
        var options = new ParallelOptions { CancellationToken = cancellationTokenSource.Token };

        Task.Factory.StartNew(() =>
        {
            if (CancellationRequested) cancellationTokenSource.Cancel();
        });

        try
        {
            Parallel.For(0, numberOfStuffToDo, options, a =>
            {
                options.CancellationToken.ThrowIfCancellationRequested();
                var class1 = new Class1();
                var class2 = new Class2();
                var class3 = new Class3();
                var class4 = new Class4(class1, class2, class3);
                var result = class4.DoStuff();
                StuffResults.Add(result);
            });
        }
        catch (OperationCanceledException e)
        {
            //handle exception
        }
    }
}  

问题:如何避免每次迭代都实例化一个新的Class1Class2Class3Class4 对象?我读了thismsdn 的文章,但我不明白。每个线程可能每个对象 1 个。

【问题讨论】:

    标签: c# asp.net-mvc multithreading parallel-extensions


    【解决方案1】:

    对我来说它看起来很安全......

    如果类涉及某种状态,那么我不知道您是否可以避免实例化它们。如果没有,您可以在循环外声明类或将 DoStuff 方法设为静态,这样您就根本不需要实例化类。

    【讨论】:

      【解决方案2】:

      我会这样做:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading;
      using System.Threading.Tasks;
      
      namespace ParallelTest
      {
          class Program
          {
              static AutoResetEvent autoReset = new AutoResetEvent(false);
      
              static void Main(string[] args)
              {
                  // since this is an async method it will be run in a different thread
                  DoSomething();
      
                  // wait for the async method to signal the main thread
                  autoReset.WaitOne();
      
                  Console.WriteLine("done");
      
              }
      
              async static void DoSomething()
              {
                  // create some common data
                  const int count = 50000;
                  const int factor = 3;
      
      
                  // create some tasks
                  var task1 = Task.Run(() =>
                  {
                      int x = 0;
                      for (int i = 0; i < count * 2; ++i)
                      {
                          x += i + factor * 3;
                          Console.WriteLine("task1: " + i + factor * 3);
                      }
                      return x;
                  });
      
                  var task2 = Task.Run(() =>
                  {
                      int x = 0;
                      for (int i = 0; i < count * 2; ++i)
                      {
                          x += i + factor * 4;
                          Console.WriteLine("task2: " + i + factor * 4);
                      }
                      return x;
                  });
      
                  var task3 = Task.Run(() =>
                  {
                      int x = 0;
                      for (int i = 0; i < count * 2; ++i)
                      {
                          x += i + factor * 5;
                          Console.WriteLine("task3: " + i + factor * 5);
                      }
                      return x;
                  });
      
      
                  // create a resulttask which will run all the tasks in parallel
                  var resultTask = Task.WhenAll(task1, task2, task3);
      
                  // start the task and wait till it finishes
                  var results = await resultTask;
      
                  // display the results
                  for (int i = 0; i < results.Length; ++i)
                  {
                      Console.WriteLine("result" + i + ": " + results[i]);
                  }
      
                  // signal main thread
                  autoReset.Set();
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-16
        相关资源
        最近更新 更多