来自静态帮助程序方法的 C# SmtpClient SendAsync?
C# SmtpClient SendAsync from Static Helper Method?
我正在尝试编写帮助程序 class 以在我的 C# 应用程序中发送电子邮件。我想使用 SmtpClient.SendAsync
,但显然我不了解异步内容的工作原理,或者我设置了错误:
public class EmailService
{
public static void SendMessage(MailMessage message)
{
var client = new SmtpClient("127.0.0.1", 25);
client.SendCompleted += (s, e) =>
{
if (e.Error != null)
{
// TODO: Log the SMTP error somewhere
}
var callbackClient = s as SmtpClient;
var callbackMessage = e.UserState as MailMessage;
callbackClient.Dispose();
callbackMessage.Dispose();
};
client.SendAsync(message, message);
}
}
这会导致以下异常:
An asynchronous operation cannot be started at this time. Asynchronous
operations may only be started within an asynchronous handler or
module or during certain events in the Page lifecycle. If this
exception occurred while executing a Page, ensure that the Page is
marked <%@ Page Async="true" %>. This exception may also indicate an
attempt to call an "async void" method, which is generally unsupported
within ASP.NET request processing. Instead, the asynchronous method
should return a Task, and the caller should await it.
基于这个异常,听起来我的 SendMessage
方法可能需要 return 一个 Task
。但是,client.SendAsync
return 无效,因此似乎没有任何 Task
到 return 或 await
.
您应该使用 SendMailAsync()
,其中 returns 一个 Task
。
通用异步用法
要使用 async
方法,您的方法必须标记为 async
(一直到调用堆栈)。当你有异步方法时,你真的想避免使用 void return 类型。大多数时候你应该 return 一个 Task
(或者 Task<T>
如果你的方法有一个现有的 return 类型)。您还应该使用 SendMailAsync,它使用新的基于任务的异步方法。最后,您需要 await
调用异步方法。
public class EmailService
{
public static async Task SendMessage(MailMessage message)
{
using (var client = new SmtpClient("127.0.0.1", 25))
{
await client.SendMailAsync(message, message);
}
}
}
仅适用于 Web 表单
在 Web 窗体中使用异步有点棘手。您必须将页面标记为异步。
<%@ Page Async="true" %>
您会注意到 Web 窗体的一件事是您无法将方法更改为 return ASP.NET 生命周期事件的任务。所以你需要注册任务。
public void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(SendMessage));
}
但是,我们需要能够将消息传递给函数。所以我们将使用 lambda。
public void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(() => EmailService.SendMessage(message)));
}
我正在尝试编写帮助程序 class 以在我的 C# 应用程序中发送电子邮件。我想使用 SmtpClient.SendAsync
,但显然我不了解异步内容的工作原理,或者我设置了错误:
public class EmailService
{
public static void SendMessage(MailMessage message)
{
var client = new SmtpClient("127.0.0.1", 25);
client.SendCompleted += (s, e) =>
{
if (e.Error != null)
{
// TODO: Log the SMTP error somewhere
}
var callbackClient = s as SmtpClient;
var callbackMessage = e.UserState as MailMessage;
callbackClient.Dispose();
callbackMessage.Dispose();
};
client.SendAsync(message, message);
}
}
这会导致以下异常:
An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller should await it.
基于这个异常,听起来我的 SendMessage
方法可能需要 return 一个 Task
。但是,client.SendAsync
return 无效,因此似乎没有任何 Task
到 return 或 await
.
您应该使用 SendMailAsync()
,其中 returns 一个 Task
。
通用异步用法
要使用 async
方法,您的方法必须标记为 async
(一直到调用堆栈)。当你有异步方法时,你真的想避免使用 void return 类型。大多数时候你应该 return 一个 Task
(或者 Task<T>
如果你的方法有一个现有的 return 类型)。您还应该使用 SendMailAsync,它使用新的基于任务的异步方法。最后,您需要 await
调用异步方法。
public class EmailService
{
public static async Task SendMessage(MailMessage message)
{
using (var client = new SmtpClient("127.0.0.1", 25))
{
await client.SendMailAsync(message, message);
}
}
}
仅适用于 Web 表单
在 Web 窗体中使用异步有点棘手。您必须将页面标记为异步。
<%@ Page Async="true" %>
您会注意到 Web 窗体的一件事是您无法将方法更改为 return ASP.NET 生命周期事件的任务。所以你需要注册任务。
public void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(SendMessage));
}
但是,我们需要能够将消息传递给函数。所以我们将使用 lambda。
public void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(() => EmailService.SendMessage(message)));
}