【问题标题】:C# async/sync versions of Web Call return different typesWeb Call 的 C# 异步/同步版本返回不同的类型
【发布时间】:2018-09-30 05:20:20
【问题描述】:

我仍然是 async/await 新手,但我认为我对它有了更好的把握。我正在写关于如何处理某种情况的建议。场景是,某个 Web 服务有一个方法同时具有同步和异步版本,但版本具有不同的返回类型。

getDocs() 返回document[],这就是我想要的。

getDocsAsync() 返回Task<getDocsResponse>,其中getDocsResponse 具有document[] 类型的(不可等待的)属性。

为了使事情更复杂,我在传递给另一个方法的委托中调用此方法。 (我这样做是为了可以随意从服务器获取新数据,或者使用我从之前的调用中缓存的保存数据。使用保存数据的委托基本上是Task.FromResult(myDocArray)。无论是新鲜的还是缓存的,我有更多代码将处理document 对象。)

主要问题是,如果我调用异步版本,我可以等待返回值的属性吗?如果是这样,怎么做?如果没有,我是否必须等待结果才能获取属性(如response.Result)?

(简化)代码示例:调用同步方法,但包装在一个任务中。这似乎可以正常工作,如果没有 getDocs 方法的异步版本,我会这样做。

Func<Task<document[]>> f = async () => {
    var docs = Task.Run(() => service.GetDocs());
    return await docs;
}

(简化)代码示例:调用异步版本,然后...?

Func<Task<document[]>> f = async () => {
    var docs = service.GetDocsAsync();

    // this seems silly to call .Result, only to wrap it in an awaitable task.
    return await Task.FromResult(docs.Result.documents);
}

两个版本似乎都可以正常工作,但在这种情况下,异步路由似乎很尴尬。有没有更好的方法来处理这种情况?

谢谢!

【问题讨论】:

    标签: c# async-await


    【解决方案1】:

    不要在你没有使用await 的任务上使用.Result,因为它在大多数情况下会导致死锁(await vs Task.Wait - Deadlock?await works but calling task.Result hangs/deadlocks

    我认为您只想从异步委托返回 documents

    Func<Task<document[]>> f = async () => {
        Task<getDocsResponse> task = service.GetDocsAsync();
        getDocsResponse response = await task;
        return response.documents;
    }
    

    请注意,异步方法的结果始终是Task&lt;&gt;,无论您是return 的任何类型。您不需要将结果包装在 Task.FromResult 中。

    FromResult 在您需要匹配Task&lt;T&gt; 签名但只有同步方法时很有用。所以你的同步调用可能会被同步重写(除非你真的需要异步代码,但一般不建议这样做-What is the best way for wrapping synchronous code into asynchronous method

    Func<Task<document[]>> f = () => Task.FromResult(service.GetDocs());
    

    【讨论】:

    • 哦,是的,效果很好,很有意义!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 2019-01-10
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    相关资源
    最近更新 更多