Reputation: 6612
I have a WPF application which sends data to a web application through POST requests. Currently this is done with PostAsync
and that works. However, I see that certain requests finish earlier before another request finishes and that causes errors in the web application.
So I need to wait for until POST request is finished before sending the next request. I know I need to use Task
, await
and async
for this, but I'm struggling in my specific situation.
The code below is the current code, without any async
or await
, because I'm unsure how to do this due to the chaining of objects.
First I have a button click event which calls an object for exporting the data:
private void exportButton_Click(object sender, RoutedEventArgs e)
{
var dataExtractor = new DataExtractor();
// First API call
dataExtractor.ExportTestSteps(testblockId, testCase);
// Second API call
dataExtractor.ExportReportTestSteps(testCase, executionList);
}
These call a method in the DataExtractor class and after getting the right data these methods call the actual sending of the POST request:
public class DataExtractor
{
public void ExportTestSteps(string testblockId, string testCaseUniqueId)
{
...
new QualityMonitorApi().StoreReportItem(content);
}
public void ExportReportTestSteps(string testCaseUniqueId, ExecutionList executionList)
{
...
new QualityMonitorApi().StoreReportItem(content);
}
}
And the QualityMonitorApi
looks like this:
public class QualityMonitorApi
{
private string baseUrl = "http://localhost:3000/api/v1";
private static readonly HttpClient Client = new HttpClient();
public void StoreReportItem(string content)
{
string url = baseUrl + "/data_extractor/store_report_item";
var json = new StringContent(content, Encoding.UTF8, "application/json");
Client.PostAsync(url, json);
}
}
Due to the chaining of the classes I'm confused how to make sure API call 2 waits for API call 1 to finish?
Upvotes: 0
Views: 2443
Reputation: 851
You cannot do that way ? async void
is okay, as long as it is an event handler method.
Also, you can store the objects that calls the API (i.e. DataExtractor) to avoid re-instantiating.
private async void exportButton_Click(object sender, RoutedEventArgs e)
{
var dataExtractor = new DataExtractor();
// First API call
await dataExtractor.ExportTestStepsAsync(testblockId, testCase);
// Second API call
await dataExtractor.ExportReportTestStepsAsync(testCase, executionList);
}
public class DataExtractor
{
public async Task ExportTestStepsAsync(string testblockId, string testCaseUniqueId)
{
...
await new QualityMonitorApi().StoreReportItemAsync(content);
}
public async Task ExportReportTestStepsAsync(string testCaseUniqueId, ExecutionList executionList)
{
...
await new QualityMonitorApi().StoreReportItemAsync(content);
}
}
public class QualityMonitorApi
{
private string baseUrl = "http://localhost:3000/api/v1";
private static readonly HttpClient Client = new HttpClient();
public async Task StoreReportItemAsync(string content)
{
string url = baseUrl + "/data_extractor/store_report_item";
var json = new StringContent(content, Encoding.UTF8, "application/json");
await Client.PostAsync(url, json);
}
}
See more here about async programmation: https://learn.microsoft.com/en-us/dotnet/csharp/async
Upvotes: 0
Reputation: 773
Use async/await
Your async method should look like this:
public async Task StoreReportItem(string content)
{
string url = baseUrl + "/data_extractor/store_report_item";
var json = new StringContent(content, Encoding.UTF8, "application/json");
await Client.PostAsync(url, json);
}
Next use async/await in every method:
public async Task ExportReportTestSteps(string testCaseUniqueId, ExecutionList executionList)
{
...
await new QualityMonitorApi().StoreReportItem(content);
}
and so on..
Upvotes: 1