Thread.Join() 需要帮助

发布于 2024-10-31 15:29:03 字数 501 浏览 1 评论 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()。所以这是行不通的。

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

提前致谢。

Here is my scenario.

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?*** 
} 

I thought of using CurrentThread.join(). But the current thread will be form_load(). So it will not work.

Any Suggestions on how to determine if all the threads finished their task.

Thanks in Advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

十年九夏 2024-11-07 15:29:03

编辑:好的,现在我们有了更多信息,并且知道问题实际上并不是关于用户界面的,这很简单:

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 线程。该表单可以跟踪已完成的任务数量,因此,如果它需要在一切完成后执行某些操作,它就可以这样做。

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

EDIT: Okay, now we have more information and know that the question isn't really about a user interface, it's easy:

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

Of course, using the TPL's WaitForAll is a better idea than this - if you can use it, do so. But if you're using plain threads, Join is fine.


EDIT: I've been assuming you're writing a Windows Forms application, based on the Form1_Load method. It would be helpful if you could give more context in the question.

Well, your threads are unlikely to have all finished immediately after you've started them all... and you shouldn't block the UI thread waiting for them to finish, as your UI will hang.

Instead, you should make each DoSomeWork task call back into the UI when it's finished. Either DoSomeWork could have an event you could add a handler to, or you could pass a completion handler delegate into the constructor, or perhaps it knows about the form directly and can call back itself - it depends on what it's doing really.

Anyway, when the task has effectively finished, you can post back to the UI thread using Control.BeginInvoke. The form could keep track of how many tasks has finished, so that if it needs to do something when everything has finished, it can do so.

If this doesn't help, please give more information about what you want to happen when all the tasks have finished, and what those tasks are doing.

家住魔仙堡 2024-11-07 15:29:03

如果您使用 .NET 4.0,为什么不利用 TPL:

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

此外,如果这是 ASP.NET,您最好使用 异步页面

If you are using .NET 4.0 why not taking benefit of TPL:

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

Also if this is ASP.NET you are better off using asynchronous pages.

停滞 2024-11-07 15:29:03

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

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

You can use WaitHandle.WaitAll for waiting for multiple handles - http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx

Edit - removed comment about UI thread - since this is asp.net not winforms...

甜嗑 2024-11-07 15:29:03
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
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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文