- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我对在 C# 中使用 HttpClient 感到疯狂...
我简化了我的项目,以便更容易地复制我的问题。我想要做的就是在后台调用 HttpClient.PostAsync 而不阻塞我的 UI 窗口(顺便说一句,我正在使用 WPF)。
这是我的代码(将代码精简到最小值):Bing 仅在此处用于不显示我的私有(private) Web 服务,当然它可以替换为所有其他网站。
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
try {
MyTextBlock.Text = "Waiting...";
Uri webUri = new Uri("https://www.bing.com/");
using (HttpClient client = new HttpClient()) {
using (HttpResponseMessage response = await client.PostAsync(webUri, new MultipartFormDataContent())) {
MyTextBlock.Text = await response.Content.ReadAsStringAsync();
}
}
} catch (Exception exc) {
MessageBox.Show(exc.ToString(), "Unhandled Exception");
}
}
当我的 UI 正在等待异步发布请求时,它在文本框中显示“正在等待”。当异步请求返回时,它会显示结果。不会再发生任何事情。
所以这里出现了问题,有时 PostAsync 方法根本不返回......甚至忽略了超时。当我调试时,它总是有效,但当我尝试启动应用程序时,它有时会挂起。并非总是这样,这不会使查找错误变得更容易。我尝试了很多调用异步请求的方法,但每次都是同样的问题。
我还阅读了以下博客,了解异步方法中的阻塞问题,但即使使用 ConfigureAwait 也没有区别。 http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
我只是可以想象 HttpClient 异步方法锁定主线程中存在问题,所以它导致了这个问题。 Wenn 我在 ConsoleApplication 中使用相同的代码,一切都很好。我的客户端和目的地之间有一个代理,但这根本不是问题。
有人可以复制这个问题吗?我在 .NET Framework 4.6.1 中使用 C#/WPF。
最佳答案
你不需要await
client.PostAsync(webUri, i_formData)
因为在调用返回后你不需要对结果做任何事情,你可以返回 Task
。改成这个;
public static Task<HttpResponseMessage> BasicRequest(MultipartFormDataContent i_formData)
{
Uri webUri = new Uri("https://www.bing.com");
HttpClient client = new HttpClient {
Timeout = TimeSpan.FromSeconds(1)
};
return client.PostAsync(webUri, i_formData);
}
您的Window_Load
是一个事件处理程序。您可以将其设为 async void
,这是您唯一不必返回 Task
的情况。通过使其成为 async
,您可以删除所有过于复杂的代码:
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
MyTextBlock.Text = "Waiting";
HttpResponseMessage response = await BasicRequest(new
MultipartFormDataContent());
string test = await response.Content.ReadAsStringAsync();
this.Close();
}
关于C# HttpClient - PostAsync 不返回(即使使用 ConfigureAwait),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47011139/
这个问题在这里已经有了答案: ConfigureAwait(true) not returning on the context it was awaited on (2 个答案) 关闭 2 年前。
我有一个要在 Visual Studio 中搜索的特定模式。 基本上,我想搜索包含 await 的行,但不见了 ConfigureAwait在声明的最后。 我有一些模式可以在 regex-tester
我正在开发 Blazor Server Web 应用程序,但我对使用 .ConfigureAwait(false) 感到困惑。我知道我不应该在组件代码中使用它,但我不确定嵌套代码。例如:我正在调用异步
试图了解何时应该使用 ConfigureAwait()。 据书: When an async method resumes after an await, by default it will res
我正在尝试使用 ConfigureAwait,因为我想了解它是如何工作的。 因此,我编写了以下小型控制台应用程序(实际上在 LINQPad 中运行): void Main() { // Use
我已经阅读了很多关于 async/await 编程模型的文章,仍然有一些不是很清楚的地方,我想分享一下我对这些的困惑。 假设我们有以下配置: 主要的异步方法是 public async Task Do
以为我正在处理 ConfigureAwait,然后我尝试了一个实验。 我的理解是 ConfigureAwait(false) 只有在有同步上下文的情况下才会有所作为。 ASP、WPF 等应该有上下文,
这是一些 WinForms 代码: async void Form1_Load(object sender, EventArgs e) { // on the UI thread De
我有一个在 thread1 上运行的代码。我以同步方式调用函数(使用异步方法但它不应该打扰我 - 异步方法不会将代码变为异步)。 我有一个 ConfigureAwait 设置为 false 的 awa
这个问题是在 ASP.NET WebApi 2 的上下文中提出的(不是 ASP.NET Core)。我试图对这个主题进行自己的研究,但是我找不到明确的答案。 官方MSDN documentation为
我想弄清楚是否应该在顶级请求上使用 ConfigureAwait(false)。从该主题的某种权威阅读这篇文章: http://blog.stephencleary.com/2012/07/dont-
所以我知道我通常应该在库代码中使用 ConfigureAwait(false)。异常(exception)是当我知道继续将需要调用者上下文时。但是,如果我不知道会是这样的话,我不知道该怎么办。我猜我不
如果在图书馆我有这个 public async DoSomething() { await Foo(); } 然后我将其称为 lib.DoSomething().ConfigureAwait(f
示例: static void Main(string[] args) { int counter = 0; var t = new System.Timers.Timer()
我到处都读到我应该使用 ConfigureAwait(false) 来避免死锁和出于性能原因。我们在我们的应用程序中使用 ConfigureAwait。但可能会删除 ConfigureAwaits,因
假设有这样一个方法的服务库 public async Task GetPersonAsync(Guid id) { return await GetFromDbAsync(id); } 遵循Syn
我读了这篇文章https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html - 但是我看到了一个矛盾: 我知道 UI 线程死
假设我编写了一个依赖于async 方法的库: namespace MyLibrary1 { public class ClassFromMyLibrary1 { pub
我已经阅读了一些关于 async/await 的内容,并试图通过在 UI 线程上调用 WebClient.DownloadStringTaskAsync 来重现 Windows 窗体中的死锁场景,并且
当使用 await 时,默认情况下捕获 SynchronizationContext(如果存在)并且 await 之后的代码块(延续 block )是使用该上下文执行(这会导致线程上下文切换)。 pu
我是一名优秀的程序员,十分优秀!