【发布时间】:2015-09-10 23:24:01
【问题描述】:
我有一个名为DownloadFileAsync(url, Func<RemoteFileResponse, Task> onDownloadFinished) 的方法,它执行以下操作:
- 检查缓存,如果找到,立即返回缓存并启动后台任务,查看缓存是否需要更新
- 如果未找到,则返回 null 并启动后台任务以异步下载文件
- 下载文件后,它会回调 onDownloadFinished 处理程序。
这对我来说感觉很脏,因为我需要在后台线程上执行下载,但我不能等待它,因为我希望能够立即返回缓存的文件。问题是如果我这样做,我会丢失任何异常上下文。
我能想到的一些选项:
- 使用 IProgress 接口报告缓存文件,然后在下载完成后报告下载结果。
- 将该方法拆分为两个调用(一个用于获取缓存文件)另一个用于下载/更新(不是首选方式,因为我希望将接口保留为一个方法)。
想知道是否有人对我如何做到这一点有任何其他建议?
我的方法的伪代码:
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
}
【问题讨论】:
-
请包含
DownloadFileAsync(url, Func<RemoteFileResponse, Task> onDownloadFinished)的返回类型 -
只返回一个
Task,而不是使用回调委托。 -
@ScottChamberlain 我用我正在尝试做的伪代码更新了这个问题。
-
@JustinHorst 该方法可以只返回一个
Task。如果该项目被缓存,那么该任务将很快完成并具有缓存值。如果它没有被缓存,那么任务将需要更长的时间才能完成。调用者无需知道或关心该值是否来自缓存,就像您在编写同步方法时设置它一样。 -
@JustinHorst 然后总是返回两个任务,一个用于缓存版本,一个用于未缓存版本,而不是一个任务和一个回调。
标签: c# asynchronous async-await