I saw some articles about designing a custom awaitable type:
http://books.google.com.br/books?id=1On1glEbTfIC&pg=PA83&lpg=PA83&dq=create+a+custom+awaitable+type
Now consider the example below:
<Button x:Name="BtnA"
Width="75"
Margin="171,128,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="BtnA_Click"
Content="Button A" />
<Button x:Name="BtnB"
Width="75"
Margin="273,128,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Button B" Click="BtnB_OnClick" />
and:
private async void BtnA_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Awaiting Button B..");
var sx = Observable.FromEvent<MouseButtonEventHandler,
MouseButtonEventArgs>(a => (b, c) => a(c),
add => BtnB.PreviewMouseDown += add,
rem => BtnB.PreviewMouseDown -= rem)
.Do(a => a.Handled = true)
.Take(1);
await sx;
MessageBox.Show("Button B Pressed after Button A");
}
private void BtnB_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button B Pressed Without Click in Button A");
}
Why can I await IObservable<T>
(in this case when subscription is completed), if there's no GetAwaiter()
method?
Is it implemented by the compiler? Is it possible to implement something that can await
without to explicit this method (some scenarios which interfaces is being used)?
And why isn't there something like:
public interface ITask<out T>
{
IAwaiter<T> GetAwaiter();
}
public interface IAwaiter<out T> : ICriticalNotifyCompletion
{
bool IsCompleted { get; }
T GetResult();
}
... or real interfaces to create a custom awaitable?
You can't await
something that doesn't have a GetAwaiter
method that returns something that has GetResult
, OnCompleted
, IsCompleted
and implements INotifyCompletion
.
await
an IObservable<T>
?The compiler, on top of instance methods, also accepts GetAwaiter
extensions methods. In this case Reactive Extensions's Observable
provides that extension:
public static AsyncSubject<TSource> GetAwaiter<TSource>(this IObservable<TSource> source);
For example, this is how we can make strings awaitable (which compiles but obviously won't actually work):
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);
}
await "bar";
You can supply your own implementation of GetAwaiter via an extension method if one does not exist.
http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115642.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With