繁体   English   中英

在同步调用方法中调用异步等待方法

[英]Call async await method in sync calling method

这只是在窗口服务中即时通讯的想法。 我从这段视频中得到了实现并行处理的想法。

我有两个不同的方法和一个模型类。

型号分类代码:

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

您的编译器是否不以错误突出显示您的代码?

如果在不返回任何值的情况下将方法标记为异步,则应将返回类型设置为Task而不是void:

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问题和文档中找到更多信息的阅读答案:

当您使用基于foreach周期的LINQ的Select()时,下一篇文章也可能会有用: 循环内嵌套任务

让我们从底部开始:

  1. 在实际完成异步接收HttpResponseMessage之前,请先处置客户端。 您需要使您的方法async Taskawait内部await

     public async Task SendDataAsync(Email email) { using (var client = new HttpClient()) { var response = await client.PostAsync(email); } } 
  2. 当前,您的SendDataParallel无法编译。 同样,它需要返回Task

     public Task SendEmailsAsync(IList<Email> emails) { var emailTasks = emails.Select(SendDataAsync); return Task.WhenAll(allTasks); } 
  3. 在顶部,您需要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());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM