如果没有 GetAwaiter 方法,我可以等待某些内容吗?



我看到了一些关于设计一个自定义的可用类型的文章:

http://books.google.com.br/books?id=1On1glEbTfIC&pg=PA83&lpg=PA83&dq=创建+a+自定义+可用+类型

现在考虑下面的例子:

<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" />

和:

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");
}

如果没有GetAwaiter()方法,为什么我可以await IObservable<T>(在这种情况下,当订阅完成时)?

它是由编译器实现的吗?是否有可能在不显式此方法的情况下实现await(某些场景中使用了哪些接口)?为什么没有这样的东西:

public interface ITask<out T>
{
    IAwaiter<T> GetAwaiter();
}
public interface IAwaiter<out T> : ICriticalNotifyCompletion
{
    bool IsCompleted { get; }
    T GetResult();
}

或者真实的界面来创建一个自定义的awaitable?

首先,no

您不能await没有GetAwaiter方法的东西,该方法返回具有GetResultOnCompletedIsCompleted并实现INotifyCompletion东西。

那么,你是如何awaitIObservable<T>的呢

除了实例方法之外,编译器还接受GetAwaiter扩展方法。在这种情况下,Reactive Extensions的Observable提供了扩展:

public static AsyncSubject<TSource> GetAwaiter<TSource>(this IObservable<TSource> 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

相关内容

  • 没有找到相关文章

最新更新