C# Thread.Sleep和Task.Delay在循环进程中杀死主线程

C# Thread.Sleep和Task.Delay在循环进程中杀死主线程,c#,asp.net,multithreading,asynchronous,task,C#,Asp.net,Multithreading,Asynchronous,Task,我试图在循环异步电子邮件发送者中的每条消息之间添加10秒的延迟。延迟的原因是限制在给定时间段内发送的电子邮件数量 这是可行的,但只要我使用Thread.Sleep或Task.delay将10秒延迟添加到循环中,主线程似乎就会停止,因此只发送第一封电子邮件 这是我的密码: Task t=Task.Run(异步()=> { foreach(消息中的var消息) { 使用(var-client=new-SmtpClient()) { 等待client.SendMailAsync(消息); Dispos

我试图在循环异步电子邮件发送者中的每条消息之间添加10秒的延迟。延迟的原因是限制在给定时间段内发送的电子邮件数量

这是可行的,但只要我使用Thread.Sleep或Task.delay将10秒延迟添加到循环中,主线程似乎就会停止,因此只发送第一封电子邮件

这是我的密码:

Task t=Task.Run(异步()=>
{
foreach(消息中的var消息)
{
使用(var-client=new-SmtpClient())
{
等待client.SendMailAsync(消息);
Dispose();
}
//所有这些似乎都扼杀了主线
//系统。线程。线程。睡眠(时间跨度。从秒(10));
等待任务延迟(时间跨度从秒(10));
//等待新任务(()=>Task.Delay(TimeSpan.FromSeconds(10));
}
} );

我看了,但是看起来我正在使用解决方案,这对我来说不起作用。有什么想法吗?

你没有在等待第一个任务,因此它就成了一个让人欲罢不能的任务。如果下一行是控制台应用程序的
Main()
,那么程序将在其余任务完成之前退出!消除延迟将增加其他任务及时完成的概率

这是一个ASP.NET web应用程序

在这种情况下,您应该“一路”使用
async
,这意味着您不仅应该在此处使用
wait

Task t = Task.Run( async ( ) => { ... }
…成为

await Task.Run( async ( ) => { ... }
…还包括整个调用树,一直返回到ASP.NET控制器方法

public async Task SomeMethodOnMyController ()
{
    await SomethingAsync();
}

async Task SomethingAsync()
{
   // do something thrilling here

   await _emailSystem.SendEmailsAsync();

   // do something thrilling here
}
…其中
sendmailsasync
基本上是问题中提供的代码

如果不这样做,则ASP.NET可能不知道该方法正在执行异步操作,并且可能在电子邮件处理完成之前过早地回收AppDomain

编辑:对于ASP.NET WebForms 例如

protected async void OnClick(object sender, EventArgs e)
{
    await // rest of code here;
}
告诉我更多

我的理解是,
wait Task.Delay()
不会挂起整个线程,而只是挂起您想要挂起的单个任务。同一线程上的所有其他任务都可以继续运行。您不必等待第一个
t
任务,从而使其成为一个先发后忘的任务。如果下一行是控制台应用程序的
Main()
,则程序将在其余任务完成之前退出。消除延迟将增加其他任务及时完成的概率。请发布更多的代码。i、 e.控制台应用程序?WinForms?下一行是什么?谢谢各位。这是一个ASP.NET web应用程序。这就是我所有的密码。它从
列表
传入
System.Net.Mail.MailMessage
,创建
SmtpClient
,并异步发送电子邮件。是否要我添加可运行的示例?为什么要在ASP.NET应用程序中延迟?这毫无意义。嗨@Henk,ASP.NET应用程序中的延迟实际上是在指定时间段内发送多封电子邮件的延迟。我们的邮件服务要求我们每分钟最多发送30封邮件,否则我们可能会被标记为垃圾邮件。在批量提醒中添加延迟限制了每分钟发送的电子邮件数量,并使我们处于垃圾邮件雷达之下。不是雄辩的,而是一个简单的解决方案。另一种选择是购买批量电子邮件服务,我们最终会购买,但这都是额外的$$$。嗨@MickeyD。这对我来说根本不管用。电子邮件的异步处理工作得非常好(没有强加的延迟)。这是Web表单BTW,因此UI启动调用并将电子邮件列表传递给该方法。从那里,新的线程接管,一切都很好。。。除非我故意拖延@什么不起作用。你有错误吗?您可能需要显示您的UI回调method@MickeyD没问题,谢谢,我将为您准备一个可运行的示例。@MickeyD我怀疑我试图实现的目标不受支持,并指出延迟电子邮件处理的整个前提需要一个适当的解决方案,而不是“黑客”来限制在给定时间范围内发送的电子邮件数量。我试图在创建一个可运行的示例,但这只是在延迟中构建,然后结果突然出现在UI中。糟糕的代码,对线程的理解很少,最终还是一个糟糕的主意。也就是说,我感谢您的努力和耐心,现在我对线程和SendGrid等电子邮件服务的存在有了更好的理解,这些服务是专为处理大量电子邮件而设计的。