Even though in my current project we use .NET 4.5 we still have lots of references to internal libraries targeting .NET 4.0. Usually it is not a problem, however some of these libraries follow Asynchronous Programming Model pattern. This approach makes the code quite ugly because we end up with lots of nested callbacks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// rest of the code omitted for brevity private static void GetHostEntryIAsyncResultPattern() { DnsService dnsService = new DnsService(); dnsService.BeginGetHostEntry(GoogleHost, googleAsyncResult => { var googleHostResult = dnsService.EndGetHostEntry(googleAsyncResult); Console.WriteLine($"Result from IAsyncResultPattern: {GoogleHost} - {FormatHostEntry(googleHostResult)}"); dnsService.BeginGetHostEntry(YahooHost, yahooAsyncResult => { var yahooHostResult = dnsService.EndGetHostEntry(yahooAsyncResult); Console.WriteLine($"Result from IAsyncResultPattern: {YahooHost} - {FormatHostEntry(yahooHostResult)}"); }, null); }, null); } // rest of the code omitted for brevity |
Fortunately thanks to
1 |
Task.Factory.FromAsync |
method it is possible to quite easily make Begin/End methods work with async/await pattern. All you have to do is to pass Begin/End methods as an arguments to Task.Factory.FromAsync and you are good to go. The original code after refactoring looks like that
1 2 3 4 5 6 7 8 |
// rest of the code omitted for brevity var dnsService = new DnsService(); var googleHostResult = await Task.Factory.FromAsync((callback, stateObject) => dnsService.BeginGetHostEntry(GoogleHost, callback, stateObject), dnsService.EndGetHostEntry, null); Console.WriteLine($"Result from async/await: {GoogleHost} - {FormatHostEntry(googleHostResult)}"); var yahooHostResult = await Task.Factory.FromAsync((callback, stateObject) => dnsService.BeginGetHostEntry(YahooHost, callback, stateObject), dnsService.EndGetHostEntry, null); Console.WriteLine($"Result from async/await: {YahooHost} - {FormatHostEntry(yahooHostResult)}"); // rest of the code omitted for brevity |
I think everyone will agree with me that refactored version is much better than original one.
Source code for this post can be found here