如何将 EventHandler<MyMessage> 参数转换为 async/await?

How to convert EventHandler<MyMessage> parameter into async/await?

我必须消费以下 API(基本上我必须在 Stan 中订阅 subject/channel/topic):

IStanSubscription Subscribe(string subject, StanSubscriptionOptions options, EventHandler<StanMsgHandlerArgs> handler);

我想将 EAP 模式转换为 TAP 模式。我所做的如下:

public Task<MyMessage> Subscribe(string subject)
{
    var tcs = new TaskCompletionSource<MyMessage>();

    _stanConnection.Subscribe(subject, GetStanSubscriptionOptions(), (sender, args) =>
    {
        string messageAsString = Encoding.UTF8.GetString(args.Message.Data, 0, args.Message.Data.Length);

        try
        {
            args.Message.Ack();

            MyMessage message = JsonConvert.DeserializeObject<MyMessage>(messageAsString);

            tcs.SetResult(message);

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    });

    return tcs.Task;
}

第一条消息一切正常,但下一条消息抛出以下异常:

An attempt was made to transition a task to a final state when it had already completed

我读了一些文章和主题,例如:

据我所知(我对 EventHandler 不太擅长我的高级应用程序)在这两种情况下,他们都直接从 class 访问 EventHandler,在我的情况下,EventHandler 作为参数传递,我是不确定如何取消订阅。

干杯!

i would like to convert EAP pattern to TAP pattern.

如果 API 是用 EAP 模式编写的,那将有效。但事实并非如此。相反,它采用自己的订阅模式,使用委托来触发更新。

那么,您的选择是:

  1. 将自定义订阅模式映射到标准 Observable pattern
  2. 构建缓冲区(例如,System.Threading.Channels),让事件处理程序将项目添加到缓冲区,然后将它们作为异步流使用。

对于这两个选项,请务必同时处理“取消订阅”逻辑。