Thread.Join()需要帮助

时间:2011-04-11 20:09:13

标签: c# multithreading c#-4.0

这是我的情景。

private void Form1_Load(object sender, EventArgs e)
{
   List<tasks> listOfTasks =  GetListOfTasks()

   foreach(Task task in Tasks)
   {
      DoSomeWork work = new DoSomeWork();

      Thread workerThread = new Thread(work.CompleteTask());

      workerThread.Start();
   }

   ***How to determine if all threads have finished the task?*** 
} 

我想过使用CurrentThread.join()。但是当前的线程将是form_load()。所以它不会起作用。

有关如何确定所有线程是否完成任务的任何建议。

先谢谢。

4 个答案:

答案 0 :(得分:3)

如果您使用的是.NET 4.0,为什么不从TPL中受益:

Task.WaitAll(
    listOfTasks.Select(
        item => Task.Factory.StartNew(() => 
        {
            DoSomeWork work = new DoSomeWork();
            work.CompleteTask();
        })
    ).ToArray()
);

此外,如果这是ASP.NET,您最好使用asynchronous pages

答案 1 :(得分:3)

编辑:好的,现在我们有更多的信息,并且知道问题不是真的关于用户界面,这很容易:

List<Task> listOfTasks =  GetListOfTasks()

List<Thread> threads = new List<Thread>();
foreach(Task task in Tasks)
{
   DoSomeWork work = new DoSomeWork(task);

   Thread workerThread = new Thread(work.CompleteTask);
   workerThread.Start();
   threads.Add(workerThread);
}

// Now all the threads have started, Join on them in turn to wait
// for them to finish. DON'T DO THIS IN A UI THREAD IN A NORMAL APP.
foreach (Thread thread in threads)
{
    thread.Join();
}

当然,使用TPL的WaitForAll 比这更好 - 如果你可以使用它,那么就这样做。但是如果你使用普通线程,Join就可以了。


编辑:我一直在假设您正在编写基于Form1_Load方法的Windows窗体应用程序。如果你能在问题中给出更多的背景,那将会很有帮助。

好吧,你的线程不太可能在你启动它们之后立即完成所有...并且你不应该阻止UI线程等待让它们完成,因为你的UI将会挂起。

相反,您应该在完成后将每个DoSomeWork任务调用回UI。 DoSomeWork可能有一个事件你可以添加一个处理程序,或者你可以将一个完成处理程序委托传递给构造函数,或者它可能直接知道表单并可以自己回调 - 它取决于它正在做什么

无论如何,当任务有效完成时,您可以使用Control.BeginInvoke回发到UI线程。表单可以跟踪已完成的任务数量,因此如果所有完成后需要执行某些操作,则可以执行此操作。

如果这没有帮助,请提供更多信息,说明在完成所有任务后您想要发生什么,以及这些任务正在做什么。

答案 2 :(得分:0)

您可以使用WaitHandle.WaitAll等待多个句柄 - http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx

编辑 - 删除了关于UI线程的评论 - 因为这是asp.net而不是winforms ...

答案 3 :(得分:0)

void Main()
{
    var spooler = new Spooler();
    Random r = new Random();
    for (int i = 0; i < 10; i++)
    {
        var work = new DoSomeWork { Delay = r.Next(100, 5000) };
        spooler.Add(work);
    }
    spooler.Poll(100);
    Logger.Log("finish");
}
static class Logger
{
    internal static void Log(string msg)
    {
        Console.WriteLine("{0} says " + msg, Thread.CurrentThread.ManagedThreadId);
    }
}
public class Spooler
{
    private object _lock = new object();
    private List<DoSomeWork> _workItems = new List<DoSomeWork>();
    public void Add(DoSomeWork work)
    {
        _workItems.Add(work);
        Action whenDone = () => { lock(_lock) work.Done = true; };
        (new Thread(()=>work.CompleteTask(whenDone))).Start();        
    }
    public void Poll(int rate)
    {
        while(true)
        {
            var q = from c in _workItems
                    where c.Done == false
                    select c;
            Logger.Log("poll");
            int count = -1;
            lock(_lock)
            {       
                if(q.FirstOrDefault() == null) break;
                count = q.Count();
            }
            Logger.Log(count + " to go");
            Thread.Sleep(rate);
        }
    }
}
public class DoSomeWork
{
    public bool Done = false;
    public int Delay { get; set; }
    public void CompleteTask(Action whenDone)
    {
        Logger.Log("begin " + Delay);
        Thread.Sleep(Delay);
        Logger.Log("end");
        whenDone();
    }
}

15 says begin 2707
21 says begin 2809
12 says begin 4586
27 says begin 4822
28 says begin 242
29 says begin 2989
30 says begin 1374
31 says begin 4265
32 says begin 2679
33 says begin 4041
14 says poll
14 says 10 to go
14 says poll
14 says 10 to go
14 says poll
14 says 10 to go
28 says end
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
14 says poll
14 says 9 to go
30 says end
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
14 says poll
14 says 8 to go
32 says end
14 says poll
14 says 7 to go
15 says end
14 says poll
14 says 6 to go
21 says end
14 says poll
14 says 5 to go
29 says end
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
14 says poll
14 says 4 to go
33 says end
14 says poll
14 says 3 to go
14 says poll
14 says 3 to go
31 says end
14 says poll
14 says 2 to go
14 says poll
14 says 2 to go
14 says poll
14 says 2 to go
12 says end
14 says poll
14 says 1 to go
14 says poll
14 says 1 to go
14 says poll
14 says 1 to go
27 says end
14 says poll
14 says finish