Is a change in behavior expected?

Keyword

Await used with the expected types (.NET comes with the existing two such types, Task and Task<T> ). However, you can write your own expected type.

The msdn message states that:

you can recall the following code:

 await FooAsync(); RestOfMethod(); 

as something similar in nature:

 var t = FooAsync(); var currentContext = SynchronizationContext.Current; t.ContinueWith(delegate { if (currentContext == null) RestOfMethod(); else currentContext.Post(delegate { RestOfMethod(); }, null); }, TaskScheduler.Current); 

Is the (pseudo) code described above from an implementation of the expected type (e.g. Task ), or maybe this is exactly how the compiler deals with any expected type that is on the right of the Await ?

There is a post in the comment section below explaining the difference between TaskScheduler and SynchronizationContext.

The main difference is that the SynchronizationContext is the general mechanism for working with delegates, while the TaskScheduler is task-specific and satisfies their requirements (you can get a TaskScheduler that wraps the SynchronizationContext using TaskScheduler.FromCurrentSynchronizationContext). That's why Task Pending takes into account both points, first checking out the SynchronizationContext (as the more general mechanism that most UI frameworks support) and then returning to TaskScheduler. Waiting for another object can first use the SynchronizationContext, and then return to another mechanism specific to this particular type.

If I correctly understood the last sentence, this means that I can put any delegate that I want in the continueWith method (I mean calling t.ContinueWith in the code example above), that is, change the way Await works when used with my custom expected object.

Just in case you want to know more: http://blogs.msdn.com/b/pfxteam/archive/2009/09/22/9898090.aspx

+1
source share
1 answer

Is the (pseudo) code above executed from an implementation of the expected type (e.g. Task), or maybe this is just how the compiler deals with any expected type that is to the right of the wait keyword?

The pseudo code follows from a specific task. But it exists only to help you understand how it works, because it looks like a sequel.

The actual code generated by the compiler is very different, and it does not take into account the actual type . All he does is look for a GetAwaiter method that returns awaiter with IsCompleted , GetResult , OnCompleted . The expected implementation is one that either captures SynchronizationContext.Current or not (or does something else completely).

You can see the actual code here .

i.e. completely change how the wait works when used with my regular expected object.

You can do whatever you want, if that makes sense to you. You can even create built-in types expected using the extension method. For example, this code:

 public static Awaiter GetAwaiter(this string s) { throw new NotImplementedException(); } public abstract class Awaiter : INotifyCompletion { public abstract bool IsCompleted { get; } public abstract void GetResult(); public abstract void OnCompleted(Action continuation); } 

Allows you to compile await "bar"; . Of course, it will not work at runtime, but the compiler does not know this.

+4
source

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


All Articles