c# - 在事件处理程序上使用 lambda exp 时如何等待多个任务

标签 c# asynchronous windows-phone-8 lambda async-await

我有 2 个类 Main.cs 和 Processing.cs(简称 P 和 M)类 M 调用 P 传递一个 html 链接,P 在 tern 下载,转换为 Base64,重命名并保存文件然后返回一个将字符串返回给 M,现在我需要 M 等到所有这些都完成才能继续,但我无法做到。

我将 lambda 表达式与事件处理程序一起使用,以便能够在该函数中执行所有操作,而不是为事件触发器使用单独的函数,因此我能够返回带有 Base64 转换文件的字符串,但它只是返回空字符串,不要等到它被分配。

我以为调用 taskA.Wait() 会让它等待所有处理完成,但事实并非如此

如果有人有任何想法,我将不胜感激。

Main.cs 的调用是这样的:

Processing processing = new processing();
String _link = “http://www.something.com”;
var ResultBase64_Val = processing.FileToBase64(_link).Result;

在 Processing.cs 中,函数是:

public async Task<String> FileToBase64(String filePath)
{
    String convertedFile = "";

    WebClient client = new WebClient();
    Task taskA = Task.Factory.StartNew(() => client.OpenReadCompleted += async (object sender, OpenReadCompletedEventArgs e) =>
     {   
           byte[] buffer = new byte[e.Result.Length];
           buffer = new byte[e.Result.Length];
           await e.Result.ReadAsync(buffer, 0, buffer.Length);
           convertedFile = Convert.ToBase64String(buffer);
     });
     client.OpenReadAsync(new Uri(filePath));
     taskA.Wait();

     return convertedFile;           
    }

谢谢, 鲍勃

最佳答案

您的代码的问题在于,以 Task.Factory.StartNew 开始的任务会立即完成,远早于 OpenReadCompleted 在未来某个时间触发。也就是说,用 Task.RunTask.Factory.StartNew 包装一个自然异步的 API,比如 OpenReadAsync 无论如何都不是一个好主意。即使您以某种方式等待事件,或使用同步 OpenRead,您也会浪费池线程。

有新的WebClient.OpenReadTaskAsync方法:

public async Task<String> FileToBase64(String filePath)
{
    using (var client = new WebClient())
    using (var stream = await client.OpenReadTaskAsync(new Uri(filePath)))
    {
        // use stream.ReadAsync
    }
}

我还推荐 HttpClient 而不是 WebClient,前者支持并行的多个 HTTP 请求:

using System.Net.Http;

// ...

public async Task<String> FileToBase64(String filePath)
{
    using (var client = new HttpClient())
    using (var response = await client.GetAsync(filePath))
    using (var stream = await response.Content.ReadAsStreamAsync())
    {
        return string.Empty;
        // use stream.ReadAsync
    }
}

关于c# - 在事件处理程序上使用 lambda exp 时如何等待多个任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21867690/

相关文章:

c# - 在 C# 中使用图像路径从 Oracle 数据库中检索图像

c# - 将 Google 表格导出为 PDF 时,如何访问参数

multithreading - 如何在不等待的情况下从 channel 获取值

asynchronous - .net core 中的异步流下载

windows-phone-8 - 在 Windows Phone 8 中执行照片选择器任务或相机捕获任务后,墓碑不起作用

c# - 使用 ScheduledTaskAgent 更新锁定屏幕

c# - wpf 如何知道设置 Content 属性

c# - 使 WebAPI 操作异步?

c# - 命名空间 Windows.Phone.Speech 不可用

c# - 将控件添加到表格内的innerhtml div