c# - 将任务转换为任务<T>(包装任务,返回类型为 T)

标签 c# generics task continuewith

我已阅读 this question但就我而言,它更简单,因为我不必使用 Result 属性。所以我想知道我是否可以采用比 Stephen Cleary 的答案提供的更简单的方法。

假设我有这个简单的界面。

internal interface IBinaryDataReadable
{
    Task Load(AsyncDataReader reader);
}

该接口(interface)提供了异步加载对象的方法。它不会返回任何内容,因为加载结果是对象本身。

(该接口(interface)是内部的,因此显式实现以避免暴露实现。)

这是我加载二进制数据的方法。

data = new BinaryData();
await ((IBinaryDataReadable)data).Load(reader);

我想让这个更加流畅和详细,所以我编写了这个扩展方法

internal static Task<TData> Load<TData>(this TData data, AsyncDataReader reader)
    where TData : IBinaryDataReadable 
        => data.Load(reader).ContinueWith(t => data, TaskContinuationOptions.ExecuteSynchronously);

现在加载变成这样了。

data = await new BinaryData().Load(reader);

使用此方法有什么需要担心的吗?例如异常处理等?

最佳答案

同样可以使用 async/await 来完成,并放弃使用 ContinueWith

internal static async Task<TData> Load<TData>(this TData data, AsyncDataReader reader) 
    where TData : IBinaryDataReadable {
    await data.Load(reader);
    return data;
}

这样,如果需要的话,您甚至可以在方法中包含异常处理。 然而,扩展方法在流畅的接口(interface)方面并没有做太多事情,因为该方法返回一个需要等待的任务。

并且您必须显式调用通用扩展,否则您只是调用类型上的本地成员,该类型在等待时解析为 void ,从而导致编译错误。

data = await new BinaryData().Load<BinaryData>(reader); 

我建议将扩展方法重命名为不会与界面上现有成员冲突的方法。

data = await new BinaryData().LoadAsync(reader);

I wanted to know if use of ContinueWith introduces problems

除了无法捕获异常之外,我认为它不会引入任何问题。但这可以通过检查该案例并将其冒泡来管理。

internal static Task<TData> LoadAsync<TData>(this TData data, AsyncDataReader reader)
    where TData : IBinaryDataReadable {
    return data.Load(reader)
        .ContinueWith(t => {
            var error = t.Exception;
            if (error != null && t.IsFaulted)
                throw error;
            return data;
        }, TaskContinuationOptions.ExecuteSynchronously);
}

不过,在我看来,使用 async/await 更干净、更容易阅读和实现。

关于c# - 将任务转换为任务<T>(包装任务,返回类型为 T),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45906806/

相关文章:

c# - 你能同时使用路由和查询字符串值吗?

c# - 如何正确阻止方法直到对象计数器> 0?

c# - LINQ 选择语句。匿名方法返回异常

c# - 是否可以限制每秒的 Web 请求数?

c# - 如何在我的 XML 中找到特定节点?

java - 原始类型没有警告

typescript - 如何将两个 typescript 泛型绑定(bind)在一起

java - List<Dog> 是 List<Animal> 的子类吗?为什么 Java 泛型不是隐式多态的?

Ruby rake 打印参数,但不喜欢它在 methodcallll 上的值

java - 安排任务的最佳类(class)