gpt4 book ai didi

c# - 我被 async/await 宠坏了!现在正在为明确的任务延续而苦苦挣扎

转载 作者:太空狗 更新时间:2023-10-29 17:56:24 25 4
gpt4 key购买 nike

编辑(接受后)

可能不是很明显,但@Servy 的答案是正确的,不需要自定义实现 Unwrap在 monodroid 下 - 在我的评论中我说它不存在,但它确实存在。

结束编辑

我正在编写一堆使用我们的 RESTful 网络服务的应用程序,尽管我认为我知道如何正确使用任务,但事实证明我不知道。场景是我为 Windows 应用商店实现了代码 - 使用 async/await我需要为 MonoDroid 实现一些几乎相同的东西——它没有那个(没有一些我不想使用的构建技巧)。

我已经将这个问题的问题归结为一组简单的异步获取整数的任务,然后,在后续中,触发另一个异步任务,该任务将转换从该整数构建的字符串。在 C#5 中,这将是:

注意 - 当然我使用的是 Task.FromResult<T>在这里代替实际的异步代码

private async Task<string> GetStringAsync()
{
return await GetStringFromIntAsync(await GetIntAsync());
}

private async Task<int> GetIntAsync()
{
return await Task.FromResult(10);
}

private async Task<string> GetStringFromIntAsync(int value)
{
return await Task.FromResult(value.ToString());
}

为了将其转换为基于延续的模式,我尝试了这个:

private Task<string> GetStringAsync()
{
//error on this line
return GetIntAsync().ContinueWith(t => GetStringFromIntAsync(t.Result));
}

private Task<int> GetIntAsync()
{
return Task.FromResult(10);
}

private Task<string> GetStringFromIntAsync(int value)
{
return Task.FromResult(value.ToString());
}

但是,这是不正确的,因为 GetStringFromIntAsync方法返回 Task<string>这意味着延续最终会返回一个 Task<Task<string>>而不是 Task<string> .

我发现明确等待 GetStringFromIntAsync方法确实有效,但是:

private Task<string> GetStringAsync()
{
return GetIntAsync().ContinueWith(t =>
{
var nested = GetStringFromIntAsync(t.Result);
nested.Wait();
return nested.Result;
});
}

但问题是 - 这是正确的方法吗 - 我可以不返回调用者随后等待的某种延续吗?

我已经使用了很多任务 - 但不是像这样将不同类型的任务链接在一起(当然除了 async/await) - 感觉有点像我在这里要疯了 - 所以任何非常感谢帮助。

最佳答案

所以,首先,即使你有异步/等待,你的第二个和第三个实现的非异步/等待实现也是你应该做的。使用它除了会增加一些不必要的开销外,不会增加任何其他内容。

至于第一种情况,不,你不想使用Wait。这将阻止线程而不是允许它返回到池中。您只需要打开任务并获得它的内部任务。您可以使用 Unwrap 方法来做到这一点:

private Task<string> GetStringAsync()
{
return GetIntAsync()
.ContinueWith(t => GetStringFromIntAsync(t.Result))
.Unwrap();
}

这是一个 Unwrap 函数,如果您无法使用它,您可以使用它。

public static Task<T> Unwrap<T>(this Task<Task<T>> task)
{
var tcs = new TaskCompletionSource<T>();

task.ContinueWith(t =>
{
t.Result.ContinueWith(innerT => tcs.SetResult(innerT.Result)
, TaskContinuationOptions.OnlyOnRanToCompletion);
t.Result.ContinueWith(innerT => tcs.SetCanceled()
, TaskContinuationOptions.OnlyOnCanceled);
t.Result.ContinueWith(innerT => tcs.SetException(innerT.Exception.InnerExceptions)
, TaskContinuationOptions.OnlyOnRanToCompletion);
}
, TaskContinuationOptions.OnlyOnRanToCompletion);
task.ContinueWith(t => tcs.SetCanceled()
, TaskContinuationOptions.OnlyOnCanceled);
task.ContinueWith(t => tcs.SetException(t.Exception.InnerExceptions)
, TaskContinuationOptions.OnlyOnFaulted);

return tcs.Task;
}

关于c# - 我被 async/await 宠坏了!现在正在为明确的任务延续而苦苦挣扎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14402773/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com