Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SmtpClient.SendAsync-如何在触发回调之前停止退出应用程序?_C#_Smtpclient_Sendasync - Fatal编程技术网

C# SmtpClient.SendAsync-如何在触发回调之前停止退出应用程序?

C# SmtpClient.SendAsync-如何在触发回调之前停止退出应用程序?,c#,smtpclient,sendasync,C#,Smtpclient,Sendasync,我需要通过控制台应用程序异步发送电子邮件。我需要对回调进行一些DB更新,但是在回调代码运行之前,我的应用程序正在退出 我如何才能以一种良好的方式阻止这种情况的发生,而不是简单地猜测退出前需要等待多长时间。我可以想象异步调用被放置在某种形式的线程中?是否可以检查是否有人在等待呼叫 示例代码 在退出之前,在其上创建ManualResetEvent调用WaitOne。执行最后一次电子邮件/dbupdate时,调用ManualReset事件上的Set public static void Main(s

我需要通过控制台应用程序异步发送电子邮件。我需要对回调进行一些DB更新,但是在回调代码运行之前,我的应用程序正在退出

我如何才能以一种良好的方式阻止这种情况的发生,而不是简单地猜测退出前需要等待多长时间。我可以想象异步调用被放置在某种形式的线程中?是否可以检查是否有人在等待呼叫

示例代码


在退出之前,在其上创建ManualResetEvent调用WaitOne。执行最后一次电子邮件/dbupdate时,调用ManualReset事件上的Set


public static void Main(string[] args)
{
    object someArrows = ">>>";
    var users = Repository.GetUsers();
    SmtpClient client = new SmtpClient("Host");
    client.SendCompleted += SendCompletedCallback;
    MailAddress from = new MailAddress("system@domain.com", "System", Encoding.UTF8);
    int numRemaining = users.Length;
    using(ManualResetEvent waitHandle = new ManualResetEvent(numRemaining == 0))
    {
        object numRemainingLock = new object();
        foreach(var user in users)
        {
            MailAddress to = new MailAddress(user.Email);
            MailMessage message = new MailMessage(from, to);
            try
            {
                message.Body = "This is a test";
                message.BodyEncoding = System.Text.Encoding.UTF8;
                message.Subject = "test message 1" + someArrows;
                message.SubjectEncoding = System.Text.Encoding.UTF8;
                string userState = String.Format("Message for user id {0}", user.ID);
                client.SendCompleted += delegate
                {
                    lock(numRemainingLock)
                    {
                        if(--numRemaining == 0)
                        {
                            waitHandle.Set();
                        }
                    }
                };
                client.SendAsync(message, userState);
            }
            catch
            {
                message.Dispose();
                throw;
            }
        }
        waitHandle.WaitOne();
    }
}

您好,您能提供一个您建议如何做的示例吗?我已经更新了我的答案,向您展示了一个示例您正在设置SendCompleted+=SendCompletedCallback,但是在循环中您正在将SendCompleted分配给一个代理?这是否意味着委托代码运行,然后调用SendCompletedCallback?是的。但是请注意,调用回调的顺序并不能保证。因此,SendCompleted可以调用SendCompletedCallback 1st或my delegate 1st。

public static void Main(string[] args)
{
    object someArrows = ">>>";
    var users = Repository.GetUsers();
    SmtpClient client = new SmtpClient("Host");
    client.SendCompleted += SendCompletedCallback;
    MailAddress from = new MailAddress("system@domain.com", "System", Encoding.UTF8);
    int numRemaining = users.Length;
    using(ManualResetEvent waitHandle = new ManualResetEvent(numRemaining == 0))
    {
        object numRemainingLock = new object();
        foreach(var user in users)
        {
            MailAddress to = new MailAddress(user.Email);
            MailMessage message = new MailMessage(from, to);
            try
            {
                message.Body = "This is a test";
                message.BodyEncoding = System.Text.Encoding.UTF8;
                message.Subject = "test message 1" + someArrows;
                message.SubjectEncoding = System.Text.Encoding.UTF8;
                string userState = String.Format("Message for user id {0}", user.ID);
                client.SendCompleted += delegate
                {
                    lock(numRemainingLock)
                    {
                        if(--numRemaining == 0)
                        {
                            waitHandle.Set();
                        }
                    }
                };
                client.SendAsync(message, userState);
            }
            catch
            {
                message.Dispose();
                throw;
            }
        }
        waitHandle.WaitOne();
    }
}