Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.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# 又一个HttpClient/Async死锁_C#_Wpf_Async Await_Dotnet Httpclient - Fatal编程技术网

C# 又一个HttpClient/Async死锁

C# 又一个HttpClient/Async死锁,c#,wpf,async-await,dotnet-httpclient,C#,Wpf,Async Await,Dotnet Httpclient,我已经在这上面敲了好几个小时了,我已经在这上面举起了我的手。据我所知,我遇到了围绕HttpClient和Async的死锁 我们的目标是让一系列不相关的帖子快速连续地被解雇,等待它们全部完成,然后从resultset构建一个文档。该程序有一个WPF UI,该UI由以下按钮触发: private async void Generate_Suite_BTN_Click(object sender, RoutedEventArgs e) { var suiteBuilder = new Suit

我已经在这上面敲了好几个小时了,我已经在这上面举起了我的手。据我所知,我遇到了围绕HttpClient和Async的死锁

我们的目标是让一系列不相关的帖子快速连续地被解雇,等待它们全部完成,然后从resultset构建一个文档。该程序有一个WPF UI,该UI由以下按钮触发:

private async void Generate_Suite_BTN_Click(object sender, RoutedEventArgs e)
{
    var suiteBuilder = new SuiteBuilder();
    await Task.Run(() => suiteBuilder.worker_Run());
}
这会触发具有一些开关逻辑的worker_Run(),并最终触发具有parallel.Foreach的SendFiles(),因为文件的发送不需要按顺序进行,并且彼此无关:

private bool SendFiles()
{
    var result = Parallel.ForEach(_InfoCollection, SendFile);
    return result.IsCompleted;
}
其中每一个(并行)都在SendFile()中等待,根据我们发送的内容,SendFile()也有一些开关逻辑,但最终归结为:

var result = await Client.SendMessage ( vars );
results.Add(result.MessageId, result.StatusCode, result.HttpReason);
下面是SendMessage()中的HttpClient部分:

公共异步任务发送消息(vars)
{
var soapResponse=new XmlDocument();
尝试
{
Client.DefaultRequestHeaders.Add(“SOAPAction”,SOAPAction);
Client.Timeout=TimeSpan.FromSeconds(超时);
var content=新的StringContent(soapRequest,Encoding.UTF8,contentType);
var post=await Client.PostAsync(url、内容).ConfigureAwait(false);
var响应=发布内容;
result.StatusCode=post.StatusCode;
result.HttpReason=post.ReasonPhrase;
var sResponse=await response.ReadAsStringAsync().ConfigureAwait(false);
soapResponse.Load(sResponse);
}
捕获(例外情况除外)
{
//捕捉逻辑
}
}
我可以看到请求和响应在Fiddler中来回传递,但我在逐行调试中遇到了麻烦,因为我一点击PostSync,VS就会跳转并一直持续到程序结束,跳过所有断点。同时,请求会在TaskCanceledException超时,而在此之后应该出现的代码已经完成很长时间


我已经在这里和其他地方找到了几十个问题和答案,但它们并不能帮助我找到问题所在。大多数似乎都围绕着在异步调用上随意添加“.ConfigureAwait(false)”,但这似乎没有任何效果。

因此,在@JSteward的帮助下,他在评论中指出
Async
parralel.ForEach
不适合一起工作,因为在处理异步时应避免返回类型为void

他建议我只使用Async,从顶部(点击按钮)到底部(发送消息),这样就行了。他的指导值得称赞

此链接有助于解释为什么会出现这种情况:

SendFiles最终看起来像这样:

private async Task<bool> SendFiles()
{
    var result = _InfoCollection.Select(SendFile);
    await Task.WhenAll(result).ConfigureAwait(false);
    return true;
}
private async Task SendFiles()
{
var result=_InfoCollection.Select(SendFile);
wait Task.WhenAll(结果).configurewait(false);
返回true;
}

所有其他方法都是
async
,使用适当的
等待
,并返回
任务
任务

,因此,在@JSteward的帮助下,他在评论中指出
async
parralle.ForEach
不适合一起工作,因为在处理异步时应避免返回类型为void

他建议我只使用Async,从顶部(点击按钮)到底部(发送消息),这样就行了。他的指导值得称赞

此链接有助于解释为什么会出现这种情况:

SendFiles最终看起来像这样:

private async Task<bool> SendFiles()
{
    var result = _InfoCollection.Select(SendFile);
    await Task.WhenAll(result).ConfigureAwait(false);
    return true;
}
private async Task SendFiles()
{
var result=_InfoCollection.Select(SendFile);
wait Task.WhenAll(结果).configurewait(false);
返回true;
}

所有其他方法都是
异步的
,带有适当的
等待
,返回类型为
任务
任务

您可以发布整个方法还是所有相关的代码?我觉得这里没有足够的东西可以帮助我,尽管其他人可能可以。这里似乎缺少了一些东西。为什么没有等待
suiteBuilder.worker\u Run()
。你能发布更多的方法吗?正如@MichaelPuckettII评论的那样,没有足够的信息<代码>.ConfigureAwait(false)调用从UI线程调用大量代码的提示,该线程完全不与
wait Task.Run(()=>suiteBuilder.worker_Run())对齐。。。请阅读相应的指南和代码。返回类型是什么?如果它是空的,那就是你的问题
SendFiles
应该是
Task
,而
worker\u-Run
应该是
Task
ro
Task
。由于您的操作是最后一次IO绑定,所以您不应该以任何方式使用
Parallel.Foreach
。在文件集合上使用基本的
LINQ Select
,并使所有内容一直异步到事件处理程序。由于您的异步操作自然会
产生
Select
将并行运行它们,然后用
任务等待它们。什么时候可以发布整个方法或所有相关的代码?我觉得这里没有足够的东西可以帮助我,尽管其他人可能可以。这里似乎缺少了一些东西。为什么没有等待
suiteBuilder.worker\u Run()
。你能发布更多的方法吗?正如@MichaelPuckettII评论的那样,没有足够的信息<代码>.ConfigureAwait(false)调用从UI线程调用大量代码的提示,该线程完全不与
wait Task.Run(()=>suiteBuilder.worker_Run())对齐。。。请阅读相应的指南和代码。返回类型是什么?如果它是空的,那就是你的问题
SendFiles
应该是
Task
,而
worker\u-Run
应该是
Task
ro
Task
。由于您的操作是最后一道命令,您应该