如果没有GetAwaiter方法,我可以等待吗?
我看到一些关于设计自定义等待类型的文章:
http://books.google.com.br/books?id=1On1glEbTfIC&pg=PA83&lpg=PA83&dq=create+a+custom+awaitable+type
现在考虑以下示例:
和:
private async void BtnA_Click(object sender, RoutedEventArgs e) { MessageBox.Show("Awaiting Button B.."); var sx = Observable.FromEvent(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"); }
为什么我可以await IObservable
(在这种情况下订阅完成时),如果没有GetAwaiter()
方法?
它是由编译器实现的吗? 是否有可能实现一些可以await
而无需显式的方法(某些场景正在使用哪种场景)? 为什么不是这样的:
public interface ITask { IAwaiter GetAwaiter(); } public interface IAwaiter : ICriticalNotifyCompletion { bool IsCompleted { get; } T GetResult(); }
…或真正的界面来创建一个定制的等待?
首先, 没有 。
您无法await
没有GetAwaiter
方法的东西 ,该方法返回具有GetResult
, OnCompleted
, IsCompleted
并实现INotifyCompletion
。
那么,你怎么能await
IObservable
?
在实例方法之上,编译器也接受GetAwaiter
扩展方法。 在这种情况下,Reactive Extensions的Observable
提供了扩展:
public static AsyncSubject GetAwaiter (this IObservable source);
例如,这就是我们如何使字符串等待(编译,但显然不会实际工作):
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";
如果不存在,您可以通过扩展方法提供自己的GetAwaiter实现。
http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115642.aspx