怎么办Task.ContinueWith (......)

问题描述 投票:0回答:3

我使用HttpClient的,我想写类似的东西:

HttpClient client = ...;
Task<string> getContent()
{
    return client.GetAsync(...)
   .ContinueWith( t => t.Result.Content.ReadAsStringAsync() );
}

我知道我可以写

.ContinueWith( t => t.Result.Content.ReadAsStringAsync().Result);

但池的一个线程将被阻止。我想continueWithTask像Google Task library

我怎样才能做到呢?

UPDATE

是的,我确实需要使用,而不是异步任务/等待,我真的知道我想要什么。

UPDATE2

我修改了我的看法,现在我觉得我错在选择技术。如果有人怀疑,这里是不错的代码great example

.net task-parallel-library
3个回答
6
投票

这些天,你应该避免ContinueWith,宁愿async / await除非你有非常非常具体的原因;我怀疑这将工作:

async Task<string> getContent()
{
    var foo = await client.GetAsync(...); // possibly with .ConfigureAwait(false)
    return await foo.Content.ReadAsStringAsync(); // possibly with .ConfigureAwait(false)
}

3
投票

是的,我确实需要使用,而不是异步任务/等待,我真的知道我想要什么。

我强烈建议Marc's answer。除非你是卡在.NET 4.0(即Windows XP中)我想不出一个很好的理由不使用async / await。而且由于你使用HttpClientTask.Run不能如此。所以,请记住,这个答案是纯粹的教学,不推荐用于生产。

ContinueWith调用可以“链接”,善良,类似于Promise.then如何工作在JavaScript中,但超出的即装即用C#链接语义不是JavaScript的更加尴尬。

一方面,Task<Task<T>>类型不会自动解开。有可用的Unwrap方法。另外,使用.Result - 一个TPL遗物与ContinueWith更自然的使用 - 将包装在AggregateException,这可能会导致一个有趣的一种“瀑布”在您的内部异常可以得到深埋嵌套AggregateException实例中的例外。因此AggregateException.Flatten存在理顺后的,其实残局。哦,你应该always pass a TaskScheduler to ContinueWith

这里是第一次尝试,明确指定TaskScheduler,使用Unwrap解开嵌套的任务,并避免使用GetAwaiter().GetResult()Result代替嵌套异常:

Task<string> getContent()
{
  // I am so sorry, future coder, but I cannot use await here because <insert good reason>
  return Task.Run(()=> client.GetAsync(...))
      .ContinueWith(t => t.GetAwaiter().GetResult().Content.ReadAsStringAsync(), TaskScheduler.Default).Unwrap()
      .ContinueWith(t => t.GetAwaiter().GetResult(), TaskScheduler.Default);
}

如果你在你的代码做了很多,你可能需要使用something like .Then封装一些这方面的逻辑。哦,一定要记在评论道歉;即使未来的维护者是你自己,这只是做这样的代码礼貌的事情。 ;)


0
投票

但池的一个线程将被屏蔽

这是不是这样的,因为一旦“先行”的任务已经完成了ContinueWith委托只调用。 Result不会阻止,它是免费的,甚至同步。

第二.ResultReadAsStringAsync().Result)挡住,虽然。所以,你必须把它转换成另一种ContinueWith

在一般情况下,连续的IO的序列变成ContinueWith的序列。

在一般情况下,await最好在这里,但你指出,这不会为你工作。

© www.soinside.com 2019 - 2024. All rights reserved.