异步任务以意外顺序运行的混乱

问题描述 投票:0回答:1

我从这里调用一个方法:

public async void LoadingWindow_Loaded(object sender, RoutedEventArgs e)
{
    List<(string fileName, string folderName, string destFolder)> filesToDownload = new()
    {
        ("MainDatabase.db", "database", Database),
        ("file1.py", "Resources", Scripts),
        ("file2.py", "Resources", Scripts),
        ("file3.py", "Resources", Utils),
    };

    foreach (var (fileName, folderName, destFolder) in filesToDownload)
    {
        await Task.Run(() => blobMan.DownloadFileStdAsync(fileName, 
            folderName, destFolder, this));
        await Task.Delay(500);
    }
}

调用此函数:

public async Task DownloadFileStdAsync(string fileName, string folderName,
    string destPath, IProgressReporter progressReporter)
{
    string finalDest = Path.Combine(destPath, fileName);
    string blobName = fileName;

    BlobServiceClient blobServiceClient = new BlobServiceClient(
        "myaccount;EndpointSuffix=core.windows.net");
    BlobContainerClient containerClient = blobServiceClient
        .GetBlobContainerClient("myblob");

    try
    {
        BlobClient blobClient = containerClient
            .GetBlobClient(Path.Combine(folderName, blobName));
        progressReporter.ReportProgress(
            $"Downloading Blob '{blobName}' to '{finalDest}'.");

        using (FileStream fs = File.OpenWrite(finalDest))
        {
            await blobClient.DownloadToAsync(fs);
        }

        progressReporter.ReportProgress(
            $"Blob '{blobName}' downloaded successfully to '{finalDest}'.");
    }
    catch (Exception ex)
    {
        progressReporter.ReportProgress($"Error downloading blob: {ex.Message}");
        //System.Windows.MessageBox.Show($"error downloading {blobName}, {ex.Message}");
    }
}

由于某种原因,当执行到方法中的这一点时

DownloadFileStdAsync

await blobClient.DownloadToAsync(fs);

它跳回到方法的开头,并使用相同的

fileName
参数再次开始:

await blobClient.DownloadToAsync(fs);  // (is executed again)

因此它会弹出异常,因为正在创建的文件已在另一个线程中打开。

为什么会出现这种行为?我希望该方法在等待调用完成后继续。

c# .net wpf asynchronous async-await
1个回答
0
投票

看起来

LoadingWindow_Loaded
被调用了多次。

© www.soinside.com 2019 - 2024. All rights reserved.