Scenario:
Async ConfigureAwait and deadocks
Solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | using System.Net.Http; using System.Threading.Tasks; namespace ConsoleApplication1 { class ProgramTaskRunDeadlock { static void Main(string[] args) { string url = "http://www.google.com"; //Can lead to deadlock as this blocking the main context and so when the control goes back to method CurlUrl it does not get the context var result = CurlUrl(url).Result; } public async static Task<string> CurlUrl(string url) { using (var httpclient = new HttpClient()) { using (var response = await httpclient.GetAsync("http://www.google.com")) { return await response.Content.ReadAsStringAsync(); } } } } class ProgramTaskRunConfigureawait { static void Main(string[] args) { string url = "http://www.google.com"; //as await are now .ConfigureAwait(false), method CurlUrl would not resume on the context, but on thread pool thread //So CurlUrl can complete the Task without need of reentering the context. //note: Main method would always require the context var result = CurlUrl(url).Result; } public async static Task<string> CurlUrl(string url) { using (var httpclient = new HttpClient()) { using (var response = await httpclient.GetAsync("http://www.google.com").ConfigureAwait(false)) { return await response.Content.ReadAsStringAsync().ConfigureAwait(false); } } } } class ProgramTaskRunAsyncAllTheWay { static async Task Main(string[] args) { string url = "http://www.google.com"; //Now the context is not blocked as all waits are asynchronous. var result = await CurlUrl(url); } public async static Task<string> CurlUrl(string url) { using (var httpclient = new HttpClient()) { using (var response = await httpclient.GetAsync("http://www.google.com")) { return await response.Content.ReadAsStringAsync(); } } } } } |
No comments:
Post a Comment