“存储”任务以供日后完成

时间:2019-03-18 16:39:41

标签: c# asynchronous

我正在尝试“存储”一个异步任务以供日后完成-我已经找到了async cache示例,但这可以有效地将任务结果缓存在并发字典中,以便无需重新加载即可重新加载其结果。再次执行任务(HTML实现为here)。

基本上我要设计的是任务字典,以相关ID(GUID)作为关键。这是为了协调来自另一个位置的输入结果(由GUID相关ID标识的XML),我的目的是使任务挂起执行直到结果(可能来自队列)进入。

这行得通吗?这是我首次尝试进行适当的异步编码,但找不到与希望的解决方案类似的东西,因此我很可能会走上正确的路。

我可以有效地“存储”任务以供以后完成,并在完成时设置任务结果吗?

编辑:我刚发现TaskCompletionSource(基于this问题)可行吗?

2 个答案:

答案 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是您将用来处理数据的任何排队机制。 当然,您还必须使该代码具有线程安全性。