当前位置:  开发笔记 > 编程语言 > 正文

包装使用基于事件的异步模式的库,用于Async/Await

如何解决《包装使用基于事件的异步模式的库,用于Async/Await》经验,为你挑选了1个好方法。

我在整个代码中使用async/await模式.但是,有一个API使用基于事件的异步模式.我已经阅读了MSDN和几个StackOverflow的答案,这样做的方法是使用TaskCompletionSource.

我的代码:

public static Task Process(Stream data)
{
    var client = new ServiceClient();
    var tcs = new TaskCompletionSource();

    client.OnResult += (sender, e) =>
    {
        tcs.SetResult(e.Result);
    };

    client.OnError += (sender, e) =>
    {
        tcs.SetException(new Exception(e.ErrorMessage));
    };

    client.Send(data);

    return tcs.Task;
}

并称为:

string result = await Process(data);

或者,用于测试:

string result = Process(data).Result;

该方法总是很快返回,但是没有一个事件被触发.

如果我添加tcs.Task.Await(); 就在return语句之前,它可以工作,但是这并不能提供我想要的异步行为.

我已经比较了我在互联网上看到的各种样本,但没有看到任何差异.



1> Yuval Itzcha..:

问题在于,在您的Process方法终止后,您的ServiceClient本地变量有资格进行垃圾收集,并且可能在事件触发之前收集,因此存在竞争条件.

为了避免这种情况,我将在类型上定义ProcessAsync为扩展方法:

public static class ServiceClientExtensions
{
    public static Task ProcessAsync(this ServiceClient client, Stream data)
    {
        var tcs = new TaskCompletionSource();

        EventHandler resultHandler = null;
        resultHandler = (sender, e) => 
        {
            client.OnResult -= resultHandler;
            tcs.SetResult(e.Result);
        }

        EventHandler errorHandler = null;
        errorHandler = (sender, e) =>
        {
            client.OnError -= errorHandler;
            tcs.SetException(new Exception(e.ErrorMessage));
        };

        client.OnResult += resultHandler;
        client.OnError += errorHandler;

        client.Send(data);
        return tcs.Task;
    }
}

并像这样消耗它:

public async Task ProcessAsync()
{
    var client = new ServiceClient();
    string result = await client.ProcessAsync(stream);
}

编辑: @usr指出通常情况下,IO操作应该是保持对其调用活动的引用的操作,这不是我们在这里看到的情况.我同意他的观点,这种行为有点奇怪,应该可能表明对象的某种设计/实现问题ServiceClient.如果可能的话,我建议查看实现,看看是否有任何可能导致引用不能保持根深蒂固的内容.

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有