Here is an async/await when calling from a main function which cannot be marked async - the function must run synchronously, but because HttpClient is async, at some point, the await has to make things stop gracefully. I've read a lot about how .Result
or .Wait
can cause deadlocks, but those are the only versions that actually make the code synchronous.
Here is an example program, roughly following what the code does - note the 4 attempts in the loop - only one of them actually puts data out in the correct order. Is there something fundamentally wrong with this structure/can I not use example #3?
The closest example I can find is here and that is where the calling function can be made async, which this one cannot. I've tried making private static void Process()
an async and calling it with Task.Run(async ()=> await Process());
but it still runs out of order. The only thing that consistently works is Wait/Result
which can deadlock, particularly with HttpClient from what I've read. Any thoughts?
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace TestAsync
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("1. Calling process at {0:mm.ss.fff}", DateTime.Now);
// Call 1
Process();
Console.WriteLine("1. Calling process at {0:mm.ss.fff}", DateTime.Now);
// Call 2
Process();
Console.ReadKey();
}
private static void Process()
{
Console.WriteLine("2. Calling CallAsyncTest at {0:mm.ss.fff}", DateTime.Now);
for (int i = 1; i < 4; i++)
{
// Try 1 - doesn't work
//CallAsyncTest(i);
// Try 2 - doesn't work
//Task.Run(async () => await CallAsyncTest(i));
// Try 3 - but works not recommended
CallAsyncTest(i).Wait();
// Try 4 - doesn't work
//CallAsyncTest(i).ConfigureAwait(false); ;
}
}
private static async Task CallAsyncTest(int i)
{
Console.WriteLine("{0}. Calling await AsyncTest.Start at {1:mm.ss.fff}", i + 2, DateTime.Now);
var x = await AsyncTest.Start(i);
}
}
public class AsyncTest
{
public static async Task<string> Start(int i)
{
Console.WriteLine("{0}. Calling await Post<string> at {1:mm.ss.fff}", i + 3, DateTime.Now);
return await Post<string>(i);
}
private static async Task<T> Post<T>(int i)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (HttpClient httpClient = new HttpClient(new HttpClientHandler()))
{
using (HttpResponseMessage response = await httpClient.GetAsync("https://www.google.com"))
{
using (HttpContent content = response.Content)
{
string responseString = await content.ReadAsStringAsync();
Console.WriteLine("response");
}
}
}
return default(T);
}
}