gpt4 book ai didi

c# - 启动后台任务并立即返回

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

我有一个名为 DownloadFileAsync(url, Func<RemoteFileResponse, Task> onDownloadFinished) 的方法它执行以下操作:

  • 检查缓存,如果找到,立即返回缓存并启动后台任务以查看是否需要更新缓存
  • 如果没有找到,则返回 null 并启动后台任务以异步下载文件
  • 文件下载完成后,它会回调 onDownloadFinished 处理程序。

这对我来说感觉很脏,因为我需要在后台线程上执行下载,但我不能等待它,因为我希望能够立即返回缓存的文件。问题是如果我这样做,我会丢失任何异常上下文。

我能想到的一些选项:

  • 使用IProgress接口(interface)返回缓存文件,下载完成后返回下载结果。
  • 将该方法分成两个调用(一个用于获取缓存文件)另一个用于下载/更新(这不是首选方式,因为我想将我的接口(interface)保留为一个方法)。

想知道是否有人对我如何做到这一点有任何其他建议?

我的方法的伪代码:

Task<IFile> async DownloadFileAsync(url, Func<RemoteFileResponse, Task> onDownloadFinished)
{
var cache = await CheckCacheAsync(url);

// don't await this so the callee can use the cached file right away
// instead return the download result on the download finished callback
DownloadUrlAndUpdateCache(url, onDownloadFinished);

return cache
}

最佳答案

如果您的缓存是内存缓存,那么缓存任务比缓存结果更容易:

ConcurrentDictionary<Url, Task<IFile>> cache = ...;

Task<IFile> DownloadFileAsync(url) // no async keyword
{
return cache.GetOrAdd(url, url => DownloadUrlAsync(url));
}

private async Task<IFile> DownloadUrlAsync(url)
{
... // actual download
}

从逻辑上讲,GetOrAdd 正在执行此操作(但以线程安全且更高效的方式):

if (cache.ContainsKey(url))
return cache[url];
cache[url] = DownloadUrlAsync(url);
return cache[url];

但是请注意,这将缓存完整的任务,因此下载异常也会被缓存。

关于c# - 启动后台任务并立即返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32486294/

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