c# - 如果没有 GetAwaiter 方法,我可以 await 吗?

标签 c# .net async-await system.reactive

我看到一些关于设计自定义等待类型的文章:

http://books.google.com.br/books?id=1On1glEbTfIC&pg=PA83&lpg=PA83&dq=create+a+custom+awaitable+type

现在考虑下面的例子:

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

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

是编译器实现的吗?是否有可能实现可以 await 的东西不明确此方法(某些场景正在使用哪些接口(interface))? 为什么没有这样的东西:

public interface ITask<out T>
{
    IAwaiter<T> GetAwaiter();
}

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

...或创建自定义可等待的真实界面?

最佳答案

首先,

你不能await 东西没有GetAwaiter返回具有 GetResult东西的方法, OnCompleted , IsCompleted并实现 INotifyCompletion .

那么,你怎么能await一个IObservable<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";

关于c# - 如果没有 GetAwaiter 方法,我可以 await 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26046775/

相关文章:

c# - 如何动态更改 richTextBox 的 backColour 以在 visual studio C# 中进行控制

c# - Windows 2003 上的 .NET 应用程序性能问题

.net - .NET Remoting 真的已被弃用吗?

javascript - arguments.callee 异步时不返回可调用函数

javascript - 没有从 promise 中获得正确的数据

C# SQL Connection try/catch vs using vs try/catch w/using

c# - 如何返回 System.Collections 程序集中的命名空间列表?

c# - 如何检查 IOException 是否为 Not-Enough-Disk-Space-Exception 类型?

javascript - 与 `forEach` 使用相关的异步/等待竞争条件?

c# - 在 C# 中获取系统可空日期时间(日期时间?)的短日期