Parallel.For循环与线程局部变量

时间:2014-02-24 20:11:46

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

我有一个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对象?我读过this msdn文章,但我不明白。每个线程每个对象可能有一个。

2 个答案:

答案 0 :(得分:0)

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

如果类有某种状态涉及它们,那么我不知道你是否可以避免实例化它们。如果没有,您可能能够在循环外声明类或使DoStuff方法保持静态,因此您根本不需要实例化的类。

答案 1 :(得分:0)

我会这样做:

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