在同步调用方法中调用异步等待方法
Call async await method in sync calling method
这只是关于我在 window 服务中所做的事情的想法。
我从这个 video 得到了并行处理的想法。
我有两种不同的方法和一个模型class。
型号Class代码:
public class Email(){
public string Recipient { get; set; }
public string Message { get; set; }
}
方法是这样的:
public void LoadData(){
while(Main.IsProcessRunning){
// 1. Get All Emails
var emails = new dummyRepositories().GetAllEmails(); //This will return List<Emails>.
// 2. Send it
// After sending assume that the data will move to other table so it will not be query again for the next loop.
SendDataParallel(emails);//this will function async? even though the calling method is sync.
// This will continue here or wait until it already send?
// If it will continue here even though it will not send already
// So there's a chance to get the email again for the next loop and send it again?
}
}
//This will send email at parallel
public async void SendDataParallel(IList<Email> emails){
var allTasks = emails.Select(SendDataAsync);
await TaskEx.WhenAll(allTasks);
}
//Assume this code will send email asynchronously. (this will not send email, for sample only)
public async void SendDataAsync(Email email){
using (var client = new HttpClient())
{
client.PostAsync(email);
}
}
我只想获取所有排队的电子邮件,然后并行发送,然后等到它已经发送。
我避免在收到的每封电子邮件中使用 foreach
。
您的编译器不会突出显示您的错误代码吗?
如果您将您的方法标记为异步而它没有 return 任何值,您应该将您的 return 类型设置为 Task,而不是 void:
public async Task SendDataParallel(IList<Email> emails){
var allTasks = emails.Select(SendDataAsync);
await Task.WhenAll(allTasks);
}
你的第二种方法也应该return一个任务,否则你想在第一种方法中等待什么?
public async Task SendDataAsync(Email email){
using (var client = new HttpClient())
{
return client.PostAsync(email);
}
}
现在您可以 Select SendDataParallel 中的所有 SendDataAsync 任务和 .Wait() 它是同步模式下 LoadData 中的任务:
public void LoadData(){
while(Main.IsProcessRunning){
var emails = new dummyRepositories().GetAllEmails(); //This will return List<Emails>.
SendDataParallel(emails).Wait();
}
}
更多信息,您可以在 MSDN 上的其他 SO 问题和文档中找到阅读答案:
- Can somebody please explain async / await?
- Brief explanation of Async/Await in .Net 4.5
- how to and when use
async
and await
- Asynchronous Programming with Async and Await
当您使用基于 foreach 循环的 LINQ Select() 时,下一篇文章也可能有用:
Nested task inside loop
让我们从底部开始:
您在实际完成异步接收 HttpResponseMessage
之前处置您的客户端。你需要让你的方法 async Task
和 await
在里面:
public async Task SendDataAsync(Email email)
{
using (var client = new HttpClient())
{
var response = await client.PostAsync(email);
}
}
目前,您的 SendDataParallel
无法编译。同样,它需要 return a Task
:
public Task SendEmailsAsync(IList<Email> emails)
{
var emailTasks = emails.Select(SendDataAsync);
return Task.WhenAll(allTasks);
}
在顶部,您需要 await
on SendEmailsAsync
:
public async Task LoadDataAsync()
{
while (Main.IsProcessRunning)
{
var emails = new dummyRepositories().GetAllEmails();
await SendEmailsAsync(emails);
}
}
编辑:
如果您 运行 在 windows 服务中,您可以将其卸载到 Task.Run
并使用 async
关键字:
var controller = new Controller();
_processThread = Task.Run(async () => await controller.LoadDataAsync());
这只是关于我在 window 服务中所做的事情的想法。 我从这个 video 得到了并行处理的想法。
我有两种不同的方法和一个模型class。
型号Class代码:
public class Email(){
public string Recipient { get; set; }
public string Message { get; set; }
}
方法是这样的:
public void LoadData(){
while(Main.IsProcessRunning){
// 1. Get All Emails
var emails = new dummyRepositories().GetAllEmails(); //This will return List<Emails>.
// 2. Send it
// After sending assume that the data will move to other table so it will not be query again for the next loop.
SendDataParallel(emails);//this will function async? even though the calling method is sync.
// This will continue here or wait until it already send?
// If it will continue here even though it will not send already
// So there's a chance to get the email again for the next loop and send it again?
}
}
//This will send email at parallel
public async void SendDataParallel(IList<Email> emails){
var allTasks = emails.Select(SendDataAsync);
await TaskEx.WhenAll(allTasks);
}
//Assume this code will send email asynchronously. (this will not send email, for sample only)
public async void SendDataAsync(Email email){
using (var client = new HttpClient())
{
client.PostAsync(email);
}
}
我只想获取所有排队的电子邮件,然后并行发送,然后等到它已经发送。
我避免在收到的每封电子邮件中使用 foreach
。
您的编译器不会突出显示您的错误代码吗?
如果您将您的方法标记为异步而它没有 return 任何值,您应该将您的 return 类型设置为 Task,而不是 void:
public async Task SendDataParallel(IList<Email> emails){
var allTasks = emails.Select(SendDataAsync);
await Task.WhenAll(allTasks);
}
你的第二种方法也应该return一个任务,否则你想在第一种方法中等待什么?
public async Task SendDataAsync(Email email){
using (var client = new HttpClient())
{
return client.PostAsync(email);
}
}
现在您可以 Select SendDataParallel 中的所有 SendDataAsync 任务和 .Wait() 它是同步模式下 LoadData 中的任务:
public void LoadData(){
while(Main.IsProcessRunning){
var emails = new dummyRepositories().GetAllEmails(); //This will return List<Emails>.
SendDataParallel(emails).Wait();
}
}
更多信息,您可以在 MSDN 上的其他 SO 问题和文档中找到阅读答案:
- Can somebody please explain async / await?
- Brief explanation of Async/Await in .Net 4.5
- how to and when use
async
andawait
- Asynchronous Programming with Async and Await
当您使用基于 foreach 循环的 LINQ Select() 时,下一篇文章也可能有用: Nested task inside loop
让我们从底部开始:
您在实际完成异步接收
HttpResponseMessage
之前处置您的客户端。你需要让你的方法async Task
和await
在里面:public async Task SendDataAsync(Email email) { using (var client = new HttpClient()) { var response = await client.PostAsync(email); } }
目前,您的
SendDataParallel
无法编译。同样,它需要 return aTask
:public Task SendEmailsAsync(IList<Email> emails) { var emailTasks = emails.Select(SendDataAsync); return Task.WhenAll(allTasks); }
在顶部,您需要
await
onSendEmailsAsync
:public async Task LoadDataAsync() { while (Main.IsProcessRunning) { var emails = new dummyRepositories().GetAllEmails(); await SendEmailsAsync(emails); } }
编辑:
如果您 运行 在 windows 服务中,您可以将其卸载到 Task.Run
并使用 async
关键字:
var controller = new Controller();
_processThread = Task.Run(async () => await controller.LoadDataAsync());