【问题标题】:Notification when ReactiveCommand completesReactiveCommand 完成时的通知
【发布时间】:2017-10-19 14:29:42
【问题描述】:

我正在尝试使用 ReactiveUI ReactiveCommands 来打开和关闭已转换为 observable 的 gRPC 流。

下面显示的代码在某种程度上有效 - 连接按钮将导致流连接,并且我开始在订阅的 onNext 处理程序中接收数据。断开连接按钮也会通过取消令牌断开流。

但是,一旦执行了断开连接命令,我还希望收到通知,以便我可以清除应用程序中的一些其他状态。我知道 ReactiveCommand 的 onCompleted 永远不会被调用,因为 at any point it could be executed again,所以我的问题是 - 我怎么知道流何时被关闭?

查看

this.WhenActivated(d =>
{
    d(this.BindCommand(ViewModel, x => x.ConnectCommand, x => x.Connect));
    d(this.BindCommand(ViewModel, x => x.DisconnectCommand, x => x.Disconnect));
});

视图模型

ConnectCommand = ReactiveCommand.CreateFromObservable(
    () => appService.ApplicationStream(request)
        .TakeUntil(DisconnectCommand));
ConnectCommand.Subscribe(
    resp => 
    { 
        _logger.Debug(resp); 
    },
    () => 
    {
        // Ideally I could do something useful here, but https://stackoverflow.com/a/26599880/57215
        _logger.Debug("Never called, ReactiveCommands never OnComplete"); 
    });

ConnectCommand.IsExecuting.Subscribe(x => _logger.Debug($"is executing: {x}"));
ConnectCommand.CanExecute.Subscribe(x => _logger.Debug($"can execute: {x}"));
ConnectCommand.ThrownExceptions.Subscribe(ex =>
    throw new Exception($"Could not get data from server: {ex}"));

DisconnectCommand = ReactiveCommand.Create(
    () => { },
    ConnectCommand.IsExecuting);

服务

public IObservable<ApplicationStreamResponse> ApplicationStream(ApplicationStreamRequest request)
{
    return Observable.Create<ApplicationStreamResponse>(async (observer, token) =>
    {
        try
        {
            using (var call = _client.ApplicationStream(request, cancellationToken: token))
            {

                while (await call.ResponseStream.MoveNext())
                {
                    if (token.IsCancellationRequested) return;
                    observer.OnNext(call.ResponseStream.Current);
                }
                observer.OnCompleted();
            }
        }
        catch (RpcException e)
        {
            if (e.Status.StatusCode == StatusCode.Cancelled)
            {
                _logger.Debug($"Application stream was disconnected: {e.Status.Detail}");
                observer.OnCompleted();
            }
            observer.OnError(e);
        }
    });
}

【问题讨论】:

  • 在一个相当典型的 SO 橡皮鸭调试示例中,我得出的结论是,我不应该尝试找出 observable 何时在服务中完成,而只是使用操作在断开连接时清除应用程序状态。无论如何,我想发布这个问题,询问人们是否对一般代码有 cmets - 我对 ReactiveUI 很陌生,只是希望事情大致正确! :)

标签: system.reactive reactive-programming reactiveui


【解决方案1】:

订阅命令:

d(this.BindCommand(ViewModel, x => x.DisconnectCommand, x => x.Disconnect));
this.ViewModel.DisconnectCommand
    .Subscribe(_ => { /* command finished */});

或者创建一个bool响应属性,在DisconnectCommand代码末尾设置为true,查看视图中的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-19
    • 2014-03-27
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多