【问题标题】:Equivalent Task in .NET 2.0 [duplicate].NET 2.0 中的等效任务 [重复]
【发布时间】:2015-12-04 11:37:05
【问题描述】:

我知道 .NET 2.0 现在可能已经过时了。
但是我有想要在 .NET 2.0 下编译的代码。不幸的是,源使用.NET 4.0 System.Threading.Tasks

代码如下:

int count = GetCount();

Task[] tasks = new Task[count];

for (int p = 0; p < count; p++)
{
     int current = p;
     tasks[p] = Task.Run(() =>
     {
         // Do something here
     });
}
Task.WaitAll(tasks);

我不是线程专家 有人可以在 .NET 2.0 中重现相同的行为并给出明确的解释吗?

【问题讨论】:

  • 这个答案可以帮到你:stackoverflow.com/questions/6550933/…
  • 感谢您的评论,但是该答案仅相当于单个 Task 实例(?)我提供的代码似乎使用了多个 Task 实例,我不太确定 @987654326 是什么@做..
  • Tasks.WaitAll 就像数组中每个 Thread 对象上的 Thread.Join

标签: c# multithreading task .net-2.0


【解决方案1】:

我的解决方案是使用 BackgroundWorker 并将其包装在辅助类中。
这样您还可以指定额外的完成事件。

public delegate void Action();

public class TaskRunner
{
    private readonly object _lock = new object();
    private bool _complete;
    private int _counter;

    public void AddTask(Action action)
    {
        var worker = new BackgroundWorker();
        worker.DoWork += (sender, args) => action();
        worker.RunWorkerCompleted += (sender, args) =>
        {
            try
            {
                Monitor.Enter(_lock);
                if (--_counter == 0)
                {
                    Monitor.Pulse(_lock);
                }
            }
            finally
            {
                Monitor.Exit(_lock);
            }
        };

        try
        {
            Monitor.Enter(_lock);
            if (_complete)
            {
                throw new Exception("task runner is complete");
            }

            _counter++;
            worker.RunWorkerAsync();
        }
        finally
        {
            Monitor.Exit(_lock);
        }
    }

    public void Wait()
    {
        while (!_complete)
        {
            try
            {
                Monitor.Enter(_lock);

                if (_counter == 0)
                {
                    _complete = true;
                    return;
                }

                Monitor.Wait(_lock);
            }
            finally
            {
                Monitor.Exit(_lock);
            }
        }
    }
}

static void Main(string[] args)
{
    var task = new TaskRunner();

    for (var i = 0; i < 10; i++)
    {
        task.AddTask(() => 
        { 
            //Do something
        });
    }

    task.Wait();

    Console.WriteLine("Done");
    Console.ReadLine();
}

希望对你有帮助。

【讨论】:

  • 这个没试过,但很有趣。顺便说一句,我需要在 using 指令中添加什么命名空间才能使用BackgroundWorker?我也想知道为什么在完成时抛出异常?您能否添加 cmets,以便我可以更清楚地了解您的代码。还是谢谢!
  • 例外是因为我不想让你等待完成的任务,但你可以很容易地忽略它。 BackgroundWorker 可以在 System.ComponentModel.BackgroundWorker 中找到
【解决方案2】:
public void Start(){
    int count = GetCount();

    //create an array of Thread objects for later access
    Thread[] threads = new Thread[count];

    for (int p = 0; p < count; p++)
    {
         //Create a new Thread
         threads[p] = new Thread(DoSomething);  //.Net 2.0 doesn't have support for lambda expressions, so use a method instead
         //Start the Thread
         threads[p].Start();
    }

    //Wait for all threads to finish execution
    foreach(var t in threads){
        t.Join(); //Thread.Join blocks until the Thread finished executing
    }
}

//this method will be executed by the threads
public void DoSomething(){

}

【讨论】:

  • 这行得通,谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-10-13
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2011-08-06
  • 1970-01-01
  • 2011-08-03
  • 2012-06-05
相关资源
最近更新 更多