Up until now, I've been making synchronous HttpWebRequest calls in WinForms applications. I want to start doing it asynchronously so as to not block the UI thread and have it hang. Therefore, I am attempting to switch to HttpClient, but I am also new to async and tasks and don't quite get it, yet.
I can launch the request and get a response and isolate the data I want (result, reasonPhrase, headers, code) but don't know how to get that back for display in textBox1. I also need to capture ex.message and return to the form if a timeout or cannot connect message occurs.
Every single example I see has the values written to Console.WriteLine() at the point they are available, but I need them returned back to the form for display and processing and have a hard time understanding how.
Here's a simple example:
namespace AsyncHttpClientTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = "calling Test()...\r\n";
DownloadPageAsync();
// need to get from DownloadPageAsync here: result, reasonPhrase, headers, code
textBox1.AppendText("done Test()\r\n");
}
static async void DownloadPageAsync()
{
// ... Use HttpClient.
using (HttpClient client = new HttpClient())
{
try
{
using (HttpResponseMessage response = await client.GetAsync(new Uri("http://192.168.2.70/")))
{
using (HttpContent content = response.Content)
{
// need these to return to Form for display
string result = await content.ReadAsStringAsync();
string reasonPhrase = response.ReasonPhrase;
HttpResponseHeaders headers = response.Headers;
HttpStatusCode code = response.StatusCode;
}
}
}
catch (Exception ex)
{
// need to return ex.message for display.
}
}
}
}
}
Any helpful hints or advice?
PostAsync(String, HttpContent)Send a POST request to the specified Uri as an asynchronous operation.
The HTTP request is sent out, and HttpClient. GetAsync returns an uncompleted Task . AsyncAwait_GetSomeDataAsync awaits the Task ; since it is not complete, AsyncAwait_GetSomeDataAsync returns an uncompleted Task . Test5Controller. Get blocks the current thread until that Task completes.
The HttpClient class instance acts as a session to send HTTP requests. An HttpClient instance is a collection of settings applied to all requests executed by that instance. In addition, every HttpClient instance uses its own connection pool, isolating its requests from requests executed by other HttpClient instances.
Now, we can create a Winform application to consume the Web API and upload/download the files from web server to our local machine. Open Visual Studio 2015. Click New >> Project >> Visual C# >> Windows >> select Windows Forms Application. Enter your project name and click OK.
create a model to hold the data you want to return
public class DownloadPageAsyncResult {
public string result { get; set; }
public string reasonPhrase { get; set; }
public HttpResponseHeaders headers { get; set; }
public HttpStatusCode code { get; set; }
public string errorMessage { get; set; }
}
Avoid using async void
methods. Convert the method to async Task
and call it in the event handler where it is allowed.
private async void button1_Click(object sender, EventArgs e) {
textBox1.Text = "calling Test()...\r\n";
var result = await DownloadPageAsync();
// Access result, reasonPhrase, headers, code here
textBox1.AppendText("done Test()\r\n");
}
static HttpClient client = new HttpClient();
static async Task<DownloadPageAsyncResult> DownloadPageAsync() {
var result = new DownloadPageAsyncResult();
try {
using (HttpResponseMessage response = await client.GetAsync(new Uri("http://192.168.2.70/"))) {
using (HttpContent content = response.Content) {
// need these to return to Form for display
string resultString = await content.ReadAsStringAsync();
string reasonPhrase = response.ReasonPhrase;
HttpResponseHeaders headers = response.Headers;
HttpStatusCode code = response.StatusCode;
result.result = resultString;
result.reasonPhrase = reasonPhrase;
result.headers = headers;
result.code = code;
}
}
} catch (Exception ex) {
// need to return ex.message for display.
result.errorMessage = ex.Message;
}
return result;
}
The HttpClient
should also not be created every time the download is called.
Refer to What is the overhead of creating a new HttpClient per call in a WebAPI client?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With