gpt4 book ai didi

c# - 真实世界的异步和等待代码示例

转载 作者:行者123 更新时间:2023-11-30 17:09:01 24 4
gpt4 key购买 nike

<分区>

我一直在到处寻找 .net 4.5 中新的 Async 和 Await 功能的真实示例。我想出了以下代码来下载文件列表并限制并发下载的数量。如果有任何最佳实践或方法来改进/优化此代码,我将不胜感激。

我们使用以下语句调用以下代码。

await this.asyncDownloadManager.DownloadFiles(this.applicationShellViewModel.StartupAudioFiles, this.applicationShellViewModel.SecurityCookie, securityCookieDomain).ConfigureAwait(false);

然后我们使用事件将下载的文件添加到 ViewModel 上的 observablecollection(.net 4.5 中的新线程安全版本)。

public class AsyncDownloadManager
{
public event EventHandler<DownloadedEventArgs> FileDownloaded;

public async Task DownloadFiles(string[] fileIds, string securityCookieString, string securityCookieDomain)
{
List<Task> allTasks = new List<Task>();
//Limits Concurrent Downloads
SemaphoreSlim throttler = new SemaphoreSlim(initialCount: Properties.Settings.Default.maxConcurrentDownloads);

var urls = CreateUrls(fileIds);

foreach (var url in urls)
{
await throttler.WaitAsync();
allTasks.Add(Task.Run(async () =>
{
try
{
HttpClientHandler httpClientHandler = new HttpClientHandler();
if (!string.IsNullOrEmpty(securityCookieString))
{
Cookie securityCookie;
securityCookie = new Cookie(FormsAuthentication.FormsCookieName, securityCookieString);
securityCookie.Domain = securityCookieDomain;
httpClientHandler.CookieContainer.Add(securityCookie);
}

await DownloadFile(url, httpClientHandler).ConfigureAwait(false);
}
finally
{
throttler.Release();
}
}));
}
await Task.WhenAll(allTasks).ConfigureAwait(false);
}

async Task DownloadFile(string url, HttpClientHandler clientHandler)
{
HttpClient client = new HttpClient(clientHandler);
DownloadedFile downloadedFile = new DownloadedFile();

try
{
HttpResponseMessage responseMessage = await client.GetAsync(url).ConfigureAwait(false);
var byteArray = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

if (responseMessage.Content.Headers.ContentDisposition != null)
{
downloadedFile.FileName = Path.Combine(Properties.Settings.Default.workingDirectory, responseMessage.Content.Headers.ContentDisposition.FileName);
}
else
{
return;
}

if (!Directory.Exists(Properties.Settings.Default.workingDirectory))
{
Directory.CreateDirectory(Properties.Settings.Default.workingDirectory);
}
using (FileStream filestream = new FileStream(downloadedFile.FileName, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
{
await filestream.WriteAsync(byteArray, 0, byteArray.Length);
}
}
catch(Exception ex)
{
return;
}
OnFileDownloaded(downloadedFile);
}

private void OnFileDownloaded(DownloadedFile downloadedFile)
{
if (this.FileDownloaded != null)
{
this.FileDownloaded(this, new DownloadedEventArgs(downloadedFile));
}
}

public class DownloadedEventArgs : EventArgs
{
public DownloadedEventArgs(DownloadedFile downloadedFile)
{
DownloadedFile = downloadedFile;
}

public DownloadedFile DownloadedFile { get; set; }
}

根据 Svick 的建议 - 以下是直接问题:

  1. 在其他 Async/Await 方法中嵌入 Async/Await 有什么影响? (在 Async/Await 方法内将文件流写入磁盘。
  2. 应该为每个单独的任务使用一个 httpclient,还是应该共享一个?
  3. 事件是将下载的文件引用“发送”到 View 模型的好方法吗?[我也会在 codereview 中发帖]

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com