我正在尝试“存储”一个异步任务以供日后完成-我已经找到了async cache示例,但这可以有效地将任务结果缓存在并发字典中,以便无需重新加载即可重新加载其结果。再次执行任务(HTML实现为here)。
基本上我要设计的是任务字典,以相关ID(GUID)作为关键。这是为了协调来自另一个位置的输入结果(由GUID相关ID标识的XML),我的目的是使任务挂起执行直到结果(可能来自队列)进入。
这行得通吗?这是我首次尝试进行适当的异步编码,但找不到与希望的解决方案类似的东西,因此我很可能会走上正确的路。
我可以有效地“存储”任务以供以后完成,并在完成时设置任务结果吗?
编辑:我刚发现TaskCompletionSource(基于this问题)可行吗?
答案 0 :(得分:2)
您是否正在考虑延迟加载?您可以使用Lazy<Task>
(这将初始化任务,但不会将其排队等待运行)。
var tasks = new Dictionary<Guid, Lazy<Task>>();
tasks.Add(Task1Guid, new Lazy<Task>(() => { whatever the 1st task is }));
tasks.Add(Task2Guid, new Lazy<Task>(() => { whatever the 2nd task is }));
void async RunTaskAsync(Guid guid)
{
await tasks[guid].Value;
}
答案 1 :(得分:2)
如果我正确理解了您的用例,则可以使用TaskCompletionSource。
实现示例:
public class AsyncCache
{
private Dictionary<Guid, Task<string>> _cache;
public Task<string> GetAsync(Guid guid)
{
if (_cache.TryGetValue(guid, out var task))
{
// The value is either there or already queued
return task;
}
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
_queue.Enqueue(() => {
var result = LoadResult();
tcs.TrySetValue(result);
});
_cache.Add(guid, tcs.Task);
return tcs.Task;
}
}
在这里,_queue
是您将用来处理数据的任何排队机制。
当然,您还必须使该代码具有线程安全性。