c# - 如何使用任务有条件地异步运行代码

标签 c# .net multithreading .net-4.0 task-parallel-library

我有一个类负责检索资源,该类还缓存资源以便快速访问。 该类公开了一个用于检索资源的异步方法:

public Task<object> GetResourceAsync(string resourceName)
{
    return Task.Factory.StartNew<object>(() =>
    {
        // look in cache

        // if not found, get from disk

        // return resource
    });
}

客户端代码如下所示:

myResourceProvider.GetResourceAsync("myResource")
    .ContinueWith<object>(t => Console.WriteLine("Got resource " + t.Result.ToString()));

这样,后台线程总是被使用。但是,如果在缓存中找到对象,我不希望代码异步运行。 如果在缓存中找到它,我想立即返回资源,而不必使用另一个线程。

谢谢。

最佳答案

.NET 4.5 有 Task.FromResult 让你返回 Task<T> ,但它不是在线程池线程上运行委托(delegate),而是显式设置任务的返回值。

因此在您的代码上下文中:

public Task<object> AsyncGetResource(string resourceName)
{
    object valueFromCache;
    if (_myCache.TryGetValue(resourceName, out valueFromCache)) {
        return Task.FromResult(valueFromCache);
    }
    return Task.Factory.StartNew<object>(() =>
    {
        // get from disk
        // add to cache
        // return resource
    });
}

如果您仍在使用 .NET 4.0,则可以使用 TaskCompletionSource<T> 做同样的事情:

var tcs = new TaskCompletionSource<object>();
tcs.SetResult(...item from cache...);
return tcs.Task;

关于c# - 如何使用任务有条件地异步运行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8575889/

相关文章:

c++ - 并发 std::vector 写入的效率

java - 模拟的GUI渲染

c# - ReadOnlyCollection如何隐藏Add和Remove方法

c# - 如何使用 Mailkit/MimeKit IMAP 将所有邮件保存到单个 .mbox 文件?

c# - 为什么 DefaultIfEmpty 是这样实现的?

c# - 写入没有读取权限的文件

python - 每个线程的 CPU 使用率

c# - 在创建关闭自身的匿名函数时使用未分配的局部变量

javascript - WCF 服务在 GoDaddy 上无法运行,如何调试?

c# - 扩展列表框还是使用替代方案?