⬆️ ⬇️

We use C # 5 features (async and await) in .NET 2.0

Dedicated to those 45% of .NET developers that still sit on the frameworks 2.0-3.5.



Yes, you heard right. async and await in the second dotnet. But first things first.



What for?


At some point I got tired of manually fiddling with writing asynchronous code. Async / awat looked too tasty not to try. Knowing that Microsoft, when adding new features to the language and the compiler, does not tie them tightly to the framework (for example, extension-methods and LINQ can be perfectly used in the second .NET, if you declare System.Runtime.CompilerServices.ExtensionAttribute somewhere), and seeing Async CTP, adding the ability to use async / await to the 2010th studio when using the .NET 4.0 target framework, I thought, why not?

')

Way


Studying the results of the compiler activity and the dependencies of the framework classes, I realized that adding one attribute without a code is not enough. Need a complete implementation, but where is it to get? And then Mono comes to the rescue with its implementation of the BCL under the MIT license. Well, brazenly we swing Mono 3.10.1 and we pull out naked System.Threading.Tasks and necessary classes from System.Runtime.CompilerServices. They are dependent on a lot of things, but for the most part everything is solved by simple copying. There are two problems:



1) OperationCanceledException knows nothing about CancellationToken. We create a class OperationCancelledExceptionExt that knows. It is thrown by CancellationToken.ThrowIfCancelled, so knowing our code about it is not necessary.



2) ExceptionDispatchInfo. This is where the real problems begin. The class allows you not to lose the set-point when you re-throw an exception, which is very useful for async / await, for which everything was started. Mono implements it through the internal-method of its implementation of the Exception class, so these sources will not help us much. Well, we climb into the source code of the framework. After a cursory analysis, we understand that there is a mechanism used by runtime to support the constructs when using Remoting.

We analyze, issue the following code here (extracting the necessary Field / MethodInfo and saving the state elsewhere):



public void Throw () { try { throw _exception; } catch { InternalPreserveStackTrace.Invoke (_exception, new object[0]); RemoteStackTrace.SetValue (_exception, _stackTrace); Source.SetValue (_exception, _source); throw; } } 




We get the behavior close to the required:

There is a problem in the case where the Throw method is called.


For lack of the best solutions, we leave it like this.



We compile, we connect to the project ... We observe the picture: async / await work, but for some reason they are marked in red. It is treated by setting the correct version of the language in the project properties.



How to use


To build using Visual Studio 2010, you need to install Async CTP . To install, you need to perform a number of non-obvious actions, such as preliminary removal of MVC3 and all updates to the studio, released after SP1.

In Visual Studio 2012, I did not check, but it should start.



Next, we connect to the project MonoLib.dll and use, not forgetting to set in the project properties, that we have C # 5. A small demo is in the same place.



Additions and improvements


Since Tuple and Action / Func overloads were needed to build tasks, it was decided not to waste time on stuff and stuff LINQ2Objects into the library. If you wish, you can delete.



The MonoLib.Async.Extensions class was created where several useful extension methods were added, half of which are copied with minor changes from this document . By the way, I strongly recommend that you read the document, it is detailed how to use tasks and async / await, as well as how to properly wrap code in them that uses other models of asynchronous calls.



MonoLib.dll sources (borrowing from Mono + edits + ExceptionDispatchInfo) are available on GitHub , improve the solution in your power.

Source: https://habr.com/ru/post/179381/



All Articles