【问题标题】:Turn event into a async call将事件转换为异步调用
【发布时间】:2013-03-10 07:35:56
【问题描述】:

我正在包装一个库供我自己使用。要获得某个属性,我需要等待一个事件。我正在尝试将其包装到异步调用中。

基本上我想转

void Prepare()
{
    foo = new Foo();
    foo.Initialized += OnFooInit;
    foo.Start();
}
string Bar
{
    return foo.Bar;  // Only available after OnFooInit has been called.
}

进入这个

async string GetBarAsync()
{
    foo = new Foo();
    foo.Initialized += OnFooInit;
    foo.Start();
    // Wait for OnFooInit to be called and run, but don't know how
    return foo.Bar;
}

如何才能最好地做到这一点?我可以循环等待,但我正在尝试找到更好的方法,例如使用 Monitor.Pulse()、AutoResetEvent 或其他方法。

【问题讨论】:

    标签: c# asynchronous async-await


    【解决方案1】:

    这就是 TaskCompletionSource 发挥作用的地方。这里没有新的 async 关键字的空间。示例:

    Task<string> GetBarAsync()
    {
        TaskCompletionSource<string> resultCompletionSource = new TaskCompletionSource<string>();
    
        foo = new Foo();
        foo.Initialized += OnFooInit;
        foo.Initialized += delegate
        {
            resultCompletionSource.SetResult(foo.Bar);
        };
        foo.Start();
    
        return resultCompletionSource.Task;
    }
    

    示例使用(带有花哨的异步)

    async void PrintBar()
    {
        // we can use await here since bar returns a Task of string
        string bar = await GetBarAsync();
    
        Console.WriteLine(bar);
    }
    

    【讨论】:

    • 我猜这个函数可以包装在异步函数中?或者只是将 async 添加到函数并返回 resultCompletionSource.Task.Result;这会导致它等待?
    • 这可以包装在异步函数中,现在更新示例
    • 刚刚注意到,System.Threading.Tasks 在我的目标平台 Windows Phone 7 上不可用。有替代方案吗? (找到了this,但我想尽量减少依赖)
    • 你能做到吗?我正在使用您在同一场景中找到的库,并且无法让任务等待事件返回。也许这是库中的一个错误。
    • 我从未尝试过,因为我不想依赖更多的库。发布new question 强调这一点。
    猜你喜欢
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多