【问题标题】:What's wrong with this async Task method?这个异步任务方法有什么问题?
【发布时间】:2012-04-05 16:27:20
【问题描述】:

这只是一个简单的异步任务,但我总是遇到奇怪的编译器错误。此代码来自 ASP.NET 4 项目中的 Web API 服务,使用 VS2010 创建。

即使 ContinueWith(非泛型)隐式返回 Task,但此错误仍然存​​在。

代码:

public class TestController : ApiController
{
       public Task<HttpResponseMessage> Test()
       {
            string url = "http://www.stackoverflow.com";
            var client = new HttpClient();

            return client.GetAsync(url).ContinueWith<HttpResponseMessage>((request) =>
            {
                // Error 361 'System.Threading.Tasks.Task' does not contain a definition
                // for 'Result' and no extension method 'Result' accepting a first argument
                // of type 'System.Threading.Tasks.Task' could be found
                // (are you missing a using directive or an assembly reference?)
                var response = request.Result;
                response.EnsureSuccessStatusCode();

                // Error 364 Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>' to 'System.Net.Http.HttpResponseMessage'
                return response.Content.ReadAsStringAsync().ContinueWith<HttpResponseMessage>((read) =>
                {
                    return new HttpResponseMessage();
                });
            });
        }
}

【问题讨论】:

    标签: c# asp.net-web-api task-parallel-library async-await


    【解决方案1】:

    364 错误是完全正常的,因为您返回的是 Task&lt;Task&lt;HttpResponseMessage&gt;&gt; 而不是 Task&lt;HttpResponseMessage&gt;。一旦你修复了 361 错误也会消失。

    所以你可以Unwrap 结果:

    public Task<HttpResponseMessage> Test()
    {
        string url = "http://www.stackoverflow.com";
        var client = new HttpClient();
        return client.GetAsync(url).ContinueWith(request =>
        {
            var response = request.Result;
            response.EnsureSuccessStatusCode();
            return response.Content.ReadAsStringAsync().ContinueWith(t =>
            {
                var result = new HttpResponseMessage();
                response.CreateContent(t.Result);
                return response;
            });
        }).Unwrap();
    }
    

    【讨论】:

    • 谢谢,我完全忘记了返回值被包裹在每个 ContinueWidth 的 Task 中。您的代码现在已编译,但我不确定它是否仍按预期工作:在执行 client.GetAsync 和 response.Content.ReadAsStringAsync 调用期间线程将空闲一段时间?
    • @Tiendq,我已经使用Unwrap 用一个更好的例子更新了我的答案。这将确保在执行 HTTP 请求期间工作线程是空闲的。
    猜你喜欢
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多