1

我必须使用以下 API(基本上我必须在Stan订阅主题/频道/主题):

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 的高级应用不太了解)在这两种情况下,它们都直接从类中访问 EventHandler,在我的情况下,EventHandler 作为参数传递,我不确定如何取消订阅。

干杯!

4

1 回答 1

2

我想将 EAP 模式转换为 TAP 模式。

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

因此,您的选择是:

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

使用这两个选项,请务必处理“取消订阅”逻辑。

于 2022-01-28T14:36:37.077 回答