【问题标题】:How can I know if there are any active threads?我怎么知道是否有任何活动线程?
【发布时间】:2017-03-09 16:52:23
【问题描述】:

我有一个控制台应用程序,它在运行时通过 googles smtp 客户端发送电子邮件。

代码:

private void SendEmailThread(MailMessage message)
{
    Thread thread = new Thread(() => _mailService.SendEmail(message));
    thread.Start();
    thread.Join();
}

我如何知道所有线程何时完成?

所有完成后是否有一个全局属性设置为ThreadsRunning = 0

我想在发送完所有电子邮件后向控制台发送一条消息,并且在我没有更多线程时完成。

类似:

if(allThreadsDone){
    Console.WriteLine("All mails are sent");
}

【问题讨论】:

  • 查看这些问题:Suspending and notifying threads when there is work to doC# equivalent to java's wait and notify?。如果您不想要专门的电子邮件发件人线程,请查看Task.Run
  • 从外观上看,您的代码与_mailService.SendEmail(message); 基本相同,因为您使用的是等待线程完成的Join
  • 来自 MSDN:阻塞调用线程,直到此实例表示的线程终止,同时继续执行标准 COM 和 SendMessage 泵送。
  • @TheLethalCoder SendEmailThread 方法在循环内被调用。换句话说,我希望它能够继续处理下一封电子邮件,即使当前一封有延迟或出现故障

标签: c# multithreading


【解决方案1】:

您的代码实际上(或多或少)同步运行。这是因为Thread.Join 会阻塞调用线程,直到另一个线程结束。或者如 MSDN 所说:

阻塞调用线程,直到此实例表示的线程终止,同时继续执行标准 COM 和 SendMessage 泵送。

所以基本上你需要做的就是在最后一次调用SendEmailThread 之后打印你的消息:

Console.WriteLine("All mails are sent");

对于您想要实现的目标,我建议您查看Task.WhenAll。在你的情况下是这样的:

var tasks = new List<Task>();
foreach (var message in messages)
{
    tasks.Add(Task.Run(() => _mailService.SendEmail(message)));
}

Task waiter = Task.WhenAll(tasks);
try
{
   waiter.Wait();
}
catch {}   

if (waiter.Status == TaskStatus.RanToCompletion)
{
    Console.WriteLine("All messages sent.");
}
else
{
    Console.WriteLine("Some messages failed to send.");  
}

【讨论】:

  • 接受这个有点快。尝试了您的解决方案,但它不起作用。我正在使用 smptp 客户端的 SendAsync 方法,上面的代码在实际发送消息之前执行
  • @Ra3IDeN 上面的代码是如何做你想做的事的一个例子。您从未在问题中指定方法为async,将来提供minimal reproducible example。由于我不知道您的代码的其余部分是什么样子,这是一个如何执行此操作的示例,我相信您可以根据自己的需要对其进行定制。正如这里提到的很多,这不是一个代码编写服务。
  • 没想到这个 m8 有代码服务。正如我在问题中所问的那样,正在寻找一种方法来了解我的所有线程是否都已完成。没想到我需要比我提供的更多的代码
  • @Ra3IDeN 如果方法是async,你应该在Task 中使用await 尽管我还没有涉足这些领域,所以我无法进一步帮助你.
猜你喜欢
  • 2023-03-07
  • 2012-05-03
  • 1970-01-01
  • 2011-04-03
  • 2021-10-05
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
相关资源
最近更新 更多