I have a problem downloading the file in my c# code.
public Form1()
{
InitializeComponent();
DownloadFile().Wait();
}
private async Task DownloadFile()
{
Debug.WriteLine("Download");// appears
HttpClient client = new();
var response = await client.GetAsync("file");
Debug.WriteLine("End download");// does not display
}
Thread stop after download but the app is not showing.
Le thread 0x7d28 s'est arrêté avec le code 0 (0x0).
Le thread 0x7998 s'est arrêté avec le code 0 (0x0).
Le thread 0x269c s'est arrêté avec le code 0 (0x0).
Le thread 0x7e74 s'est arrêté avec le code 0 (0x0).
Le thread 0x534c s'est arrêté avec le code 0 (0x0).
Le thread 0x77f0 s'est arrêté avec le code 0 (0x0).
Le thread 0x70fc s'est arrêté avec le code 0 (0x0).
Le thread 0x7428 s'est arrêté avec le code 0 (0x0).
Le thread 0x5628 s'est arrêté avec le code 0 (0x0).
Le thread 0x788c s'est arrêté avec le code 0 (0x0).
Le thread 0x63f4 s'est arrêté avec le code 0 (0x0).
CodePudding user response:
don't use async / await in combination with Wait() or Result, because it will result in a deadlock.
To avoid a deadlock within a SynchronizationContext, you should use ConfigureAwait(false):
private async Task DownloadFile()
{
Debug.WriteLine("Download");// appears
HttpClient client = new();
var response = await client.GetAsync("file").ConfigureAwait(false);
Debug.WriteLine("End download");// does not display
}
CodePudding user response:
Classic HttpClient bug. When waited on the main thread causes deadlock. ConfigureAwait(false)
that exist to resolve this type of problem don't work with HttpClient
...
To doge this, you need to force the http call on a other thread. To do this, you can encapsulate the http call in a task like :
private async Task DownloadFile()
{
Debug.WriteLine("Download");
HttpClient client = new();
var response = await Task.Run(() =>await client.GetAsync("file"));
Debug.WriteLine("End download");
}
From .NET 5, HttpClient
has (finaly) synchronous method :
private void DownloadFile()
{
Debug.WriteLine("Download");
HttpClient client = new();
var response = client.Get("file");
Debug.WriteLine("End download");
}
But it's a bad practice to do heavy work in a constructor or on the main thread for UI program. Maybe you can consider to use Form.Load
event.