結果が得られない場合は、結果を返そうとしないでください。単なるを返す、Task
を完了:
public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
new Email().Send(message);
return Task.CompletedTask;
}
}
あなたは、あなたが代わりにTask.FromResult<bool>(true)
を使用することができ、事前4.6土地で立ち往生している場合。
あなたのコメントで約と混乱しています。「async...await
はusing
と互換性がありません。です。私の経験では、それはうまく動作します。あなたのメソッドが実際には非同期であった方がずっと良いでしょう。 async
メソッドを偽造するための最良の構文が何であるかではなく、それを行う方法に焦点を当てることで、より良いサービスになると思います。
補遺:
は、私はまだusing
の使用についてあなたの懸念を明確にしていません。しかし、あなたのご意見に基づいて、SmtpClient.SendAsync()
を使用したいと思われますが、async
/await
というコンテキストでそれをどのように適用するかは不明です。
残念ながら、async
/await
の前であっても、私たちは.NETで多くの非同期メソッドを使用していました。これらのメソッドでは、新しい待望のメソッドの命名規則と同じ名前が使用されました。 (明白である:それは残念なことに命名したものであり、非同期メソッドが存在していたわけではない:))。ただし、すべての場合において、古いAPIを新しいAPIに適合させることは可能です。
場合によっては、Task.FromAsync()
メソッドを使用するのと同じくらい簡単です。これは古いモデルのBegin...
/End...
をサポートしています。しかし、SmtpClient.SendAsync()
モデルは、イベントベースのコールバックアプローチであり、少し異なるアプローチが必要です。
注:SmtpClient
クラスには、Task
に準拠した非同期動作のメソッドSendMailAsync()
があることに気付きました。実際には、古いSendAsync()
メソッドを適用する必要はありません。しかし、Task
ベースの代替案が提供されていない場合に、どのようにそのような適応を行うかを示すために有用な例です。
簡単に言うと、オブジェクトのSendCompleted
イベントでTaskCompletionSource
を使用できます。上記
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
// I'm not familiar with "IdentityMessage". Let's assume for the sake
// of this example that you can somehow adapt it to the "MailMessage"
// type required by the "SmtpClient" object. That's a whole other question.
// Here, "IdentityToMailMessage" is some hypothetical method you write
// to handle that. I have no idea what goes inside that. :)
using (MailMessage mailMessage = IdentityToMailMessage(message))
using (SmtpClient smtpClient = new SmtpClient())
{
TaskCompletionSource<bool> taskSource = new TaskCompletionSource<bool>();
// Configure "smtpClient" as needed, such as provided host information.
// Not shown here!
smtpClient.SendCompleted += (sender, e) => taskSource.SetResult(true);
smtpClient.SendAsync(mailMessage, null);
await taskSource.Task;
}
}
}
非同期操作を開始し、TaskCompletionSource<bool>
のための結果を設定する(つまり、ドキュメントが参照する「コールバック」)SendCompleted
イベントのハンドラを使用します。ここではそれがどのように見えるかの輪郭があります結果値は実際に使用されることはありませんが、TaskCompletionSource
&hellipのプレーンバニラTask
のバージョンはありません; いくつかの値が必要です。
taskSource.Task
オブジェクトを直接返すのではなく、await
を使用します。これは、電子メール操作が実際に完了したときにSmtpClient
オブジェクトの廃棄を正しく処理できるためです。
「使用中」と「非同期」についてはまったく気に入らないもの(http://stackoverflow.com/questions/16566547/do-using-statements-and-await-keywords-play-nicely- in-c-sharp)? –
@AlexeiLevenkov:それは有効なコードではないと言っている例があり、 'SmtpClient.SendAsync()'がコールバックに関連して2番目の引数を取ることがわかりました。それは私が避けたかったものです。 –
OT:[SmtpClientのドキュメント](https://docs.microsoft.com/dotnet/api/system.net.mail.smtpclient)では、[MailKit](https://github.com/jstedfast/MailKit)を使用することをお勧めしています。および[MimeKit](https://github.com/jstedfast/MimeKit)を参照してください。 –