这只是关于我在窗口服务中做什么的想法。 我从这个video得到了想法,并行处理。
我有两种不同的方法和一个模型类。
模型类代码:
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
。
答案 0 :(得分:1)
编译器是否突出显示错误代码?
如果在没有返回任何值的情况下将方法标记为异步,则应将返回类型设置为“任务”,而不是“无效”:
public async Task SendDataParallel(IList<Email> emails){
var allTasks = emails.Select(SendDataAsync);
await Task.WhenAll(allTasks);
}
你的第二种方法也应该返回一个Task,否则你想要(a)在第一种方法中等待?
public async Task SendDataAsync(Email email){
using (var client = new HttpClient())
{
return client.PostAsync(email);
}
}
现在,您可以在SendDataParallel和.Wait()中选择所有SendDataAsync任务,它在LoadData中以同步模式执行任务:
public void LoadData(){
while(Main.IsProcessRunning){
var emails = new dummyRepositories().GetAllEmails(); //This will return List<Emails>.
SendDataParallel(emails).Wait();
}
}
您可以在MSDN上的其他SO问题和文档中找到更多信息阅读答案:
async
and await
当你使用基于foreach循环的LINQ的Select()时,下一篇文章也可能有用: Nested task inside loop
答案 1 :(得分:1)
让我们从底部开始:
在实际完成异步接收HttpResponseMessage
之前,请先释放客户端。您需要在内部制作async Task
和await
方法:
public async Task SendDataAsync(Email email)
{
using (var client = new HttpClient())
{
var response = await client.PostAsync(email);
}
}
目前,您的SendDataParallel
无法编译。同样,它需要返回Task
:
public Task SendEmailsAsync(IList<Email> emails)
{
var emailTasks = emails.Select(SendDataAsync);
return Task.WhenAll(allTasks);
}
在顶部,您需要await
上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());