Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET Web API异步控制器方法和死锁_C#_Asp.net_.net_Async Await_Deadlock - Fatal编程技术网

C# ASP.NET Web API异步控制器方法和死锁

C# ASP.NET Web API异步控制器方法和死锁,c#,asp.net,.net,async-await,deadlock,C#,Asp.net,.net,Async Await,Deadlock,请帮助我理解为什么这段代码会导致死锁? 我有一个asp.NETWebAPI应用程序,我试图使一些控制器方法异步 [HttpPost] [Authentication] public async Task<SomeDTO> PostSomething([FromBody] SomeDTO someDTO) { return await _service.DoSomething(someDTO); } [HttpPost]

请帮助我理解为什么这段代码会导致死锁? 我有一个asp.NETWebAPI应用程序,我试图使一些控制器方法异步


    [HttpPost]
    [Authentication]
    public async Task<SomeDTO> PostSomething([FromBody] SomeDTO someDTO)
    {
        return await _service.DoSomething(someDTO);
    }


[HttpPost]
[认证]
公共异步任务PostSomething([FromBody]SomeDTO-SomeDTO)
{
返回等待服务。完成一些事情(sometto);
}
以下是被调用的服务方法的外观:


    public async Task<SomeDTO> DoSomething(SomeDTO someDTO)
    {
...
        var someTask = Task.Run(() => 
        {
            var entity = new SomeEntity(someDTO);
            return _repository.Create(entity);
        });
...
        var result = await someTask;
...
    }


公共异步任务DoSomething(SomeDTO SomeDTO)
{
...
var someTask=Task.Run(()=>
{
var实体=新的SomeEntity(someDTO);
返回_repository.Create(实体);
});
...
var result=等待某项任务;
...
}
还有一些globalhandler,它向控制台打印响应


    public class AppGlobalHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var resp = base.SendAsync(request, cancellationToken);
            Debug.WriteLine($"Response:{request.RequestUri}{Environment.NewLine}{resp?.ConfigureAwait(false).GetAwaiter().GetResult()?.Content?.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult()}");
            return resp;
        }
    }


公共类AppGlobalHandler:DelegatingHandler
{
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
var resp=base.sendaync(请求、取消令牌);
Debug.WriteLine($”响应:{request.RequestUri}{Environment.NewLine}{resp?.ConfigureAwait(false).GetAwaiter().GetResult()?.Content?.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult());
返回响应;
}
}
看起来像ConfigureAwait(false).GetAwaiter().GetResult()
阻止调用线程,但我认为ConfigureWait(false)应该可以避免这种情况,不是吗?

我认为您忽略了Task.Run()方法中的async关键字

公共异步任务DoSomething(SomeDTO SomeDTO)
{ 
var someTask=Task.Run(async()=>//只需为异步运行添加这个
{
var实体=新的SomeEntity(someDTO);
返回_repository.Create(实体);
}); 
var result=等待某项任务;
}
configurewait(false)在这里对您没有帮助,因为它必须一直在调用堆栈中(请参阅更多)而不是在同步等待的位置,也就是说,它取决于base.SendAsync的实现。如果它在当前线程上获得了一个锁,那么就太晚了。在ASP.net管道中也不建议继续在其他线程上响应(请参阅讨论和帖子)

最后,在异步上下文中同步等待总是一个高风险的想法。 如果您需要阅读内容,为什么不这样做:

 public class AppGlobalHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var resp = await base.SendAsync(request, cancellationToken);
        var content = resp?.Content != null 
           ? (await resp.Content.ReadAsStringAsync()) 
           : string.Empty; 
        Debug.WriteLine($"Response:{request.RequestUri}{Environment.NewLine}{content}");
        return resp;
    }
}
公共类AppGlobalHandler:DelegatingHandler
{
受保护的覆盖异步任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
var resp=await base.sendaync(请求、取消令牌);
var content=resp?.content!=null
?(等待响应内容ReadAsStringAsync())
:string.Empty;
Debug.WriteLine($“响应:{request.RequestUri}{Environment.NewLine}{content}”);
返回响应;
}
}

为什么要将代码包装到Task.Run()中?强制同步代码异步运行毫无意义,它只会使用更多线程。如果你不能一直异步,那就坚持同步。这是代码的一部分,我需要并行运行一些操作@MarcusHöglundI没有看到在你的代码中任何东西会并行运行。记住:异步!=parallel“这是代码的一部分”的意思是:我们发现死锁的可能性很小。哦,如果没有(和类似的)Debug.WriteLine()行,它会死锁吗?
 public class AppGlobalHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var resp = await base.SendAsync(request, cancellationToken);
        var content = resp?.Content != null 
           ? (await resp.Content.ReadAsStringAsync()) 
           : string.Empty; 
        Debug.WriteLine($"Response:{request.RequestUri}{Environment.NewLine}{content}");
        return resp;
    }
}