简体   繁体   English

Observable.Using()取消

[英]Observable.Using( ) cancellation

I have a observable made by the Using helper: 我有一个Using帮助器制作的可观察量:

var o = Observable.Using(
 () => { 
          return new MyResource 
       },
 res => {
          return new Observable.Create<string>(observer => ....);
        });

How can I cancel the observable? 如何取消观察? And by that make sure MyResource is disposed of? 并确保MyResource被处理掉?

I see there are a Observable.Using( ) that includes a cancellationToken , but signature is so different, that I'm not able to make it work... 我看到有一个Observable.Using( )包含了cancellationToken ,但签名是如此不同,以至于我无法让它工作......

Update: As James points out, by disposing the observable, my resource will be disposed as well. 更新:詹姆斯指出,通过处置可观察量,我的资源也将被处理掉。 In my case, a plain disposal is not enough. 在我的情况下,一个简单的处置是不够的。 I need to call a method on the resource first. 我需要先在资源上调用一个方法。 How can that be archived? 怎么归档?

You don't need to clean up an observable - just the subscription. 您不需要清理可观察的 - 只是订阅。 Simply call Dispose on the handle returned from Subscribe when you make a subscription to cancel it. 当您订阅取消Subscribe时,只需在Subscribe返回的句柄上调用Dispose

The resource created by the factory delegate supplied as the first argument to Using has a lifetime governed by lifetime of subscriptions to the observable created by Using . 由作为Using的第一个参数提供的工厂委托创建的资源具有由Using创建的可观察对的订阅的生存期控制的生存期。

Here's an example: 这是一个例子:

var xs = Observable.Using(
    () => {                        
        var resource =  Disposable.Create(() => Console.WriteLine("Binned"));
        Console.WriteLine("Created");
        return resource;
    },
    res => Observable.Never<Unit>());

Console.WriteLine("Subscribing");
var sub1 = xs.Subscribe();
var sub2 = xs.Subscribe();
Console.WriteLine("Disposing");            
sub1.Dispose();

Gives output: 给出输出:

Subscribing
Created
Created
Disposing
Binned

Since sub2 never finishes and isn't disposed, there is only a single Binned message displayed. 由于sub2从未完成并且未被处理,因此仅显示单个Binned消息。

In this example, sub1 completes immediately and there is no cancellation: 在此示例中, sub1立即完成,并且没有取消:

var xs = Observable.Using(
    () => {                        
        var resource =  Disposable.Create(() => Console.WriteLine("Binned"));
        Console.WriteLine("Created");
        return resource;
    },
    res => Observable.Return(1));

Console.WriteLine("Subscribing");
var sub1 = xs.Subscribe();

This time the resource is still cleaned up, because the subscription terminated normally: 这次资源仍然被清理,因为订阅正常终止:

Subscribing
Created
Binned

The purpose of the overload of Using sporting cancellation tokens is to allow you to cancel asynchronous creation of the resource and the dependent observable. Using运动取消令牌的重载的目的是允许您取消资源和从属观察的异步创建。 The cancellation tokens are signalled on disposal of subscription handles - of course this scenario is only really going to be useful if you have relatively lengthy creation times and early disposal is likely. 取消令牌在处理订阅句柄时发出信号 - 当然,如果您有相对较长的创建时间并且可能需要尽早处理,这种情况才会真正有用。

Addendum 附录

To address the corollary to your question: 要解决您的问题的必然结果:

...a plain disposal is not enough. ...一个简单的处置是不够的。 I need to call a method on the resource first. 我需要先在资源上调用一个方法。 How can that be [achieved]? 怎么能[实现]?

From your resource factory method (the first argument to using), do this: 从资源工厂方法(使用的第一个参数),执行以下操作:

var xs = Observable.Using(
    () =>
    {                        
        var processHandle = /* code to create process */
        return Disposable.Create(() => /* code to kill process using processHandle */;
    },
    // Rest of code...

Disposable.Create is a helper method you can use that accepts in Action that's invoked upon disposal. Disposable.Create是一个可以使用的辅助方法,它接受在处理时调用的Action

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM