Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Rx库是否忽略处理它创建的CancellationTokenSources?_C#_System.reactive_Cancellationtokensource_Cancellation Token_Rx.net - Fatal编程技术网

C# Rx库是否忽略处理它创建的CancellationTokenSources?

C# Rx库是否忽略处理它创建的CancellationTokenSources?,c#,system.reactive,cancellationtokensource,cancellation-token,rx.net,C#,System.reactive,Cancellationtokensource,Cancellation Token,Rx.net,Rx库包括接受lambda参数的操作员,其中一些lambda配有由库本身控制的控制器。这些运算符的一些示例是,StartAsync和Create: // Converts an asynchronous action into an observable sequence. Each subscription // to the resulting sequence causes the action to be started. The CancellationToken // passed

Rx库包括接受lambda参数的操作员,其中一些lambda配有由库本身控制的控制器。这些运算符的一些示例是,
StartAsync
Create

// Converts an asynchronous action into an observable sequence. Each subscription
// to the resulting sequence causes the action to be started. The CancellationToken
// passed to the asynchronous action is tied to the observable sequence's subscription
// that triggered the action's invocation and can be used for best-effort cancellation.
public static IObservable<Unit> FromAsync(Func<CancellationToken, Task> actionAsync);
输出:

令牌已取消
可观察到的结果被终止
IsCancellationRequested:True
IsDisposed:False
(.NET Framework版本,具有不同名称的专用字段)

在异步操作被取消且可观察对象终止后的半秒钟内,将检查捕获的
CancellationToken
\u disposed
字段的值为
false
,表示关联的
CancellationTokenSource
Dispose
方法未被调用。是我做错了什么,还是Rx库确实忽略了处理它创建的
CancellationTokenSource
s


.NET 5.0.1、System.Responsive 5.0.0、C#9

文档详细说明了这种情况:它说明了实现
IDisposable的任何类型。实际上,
CancellationTokenSource
只有在您使用过
.CancelAfter(…)
CancellationToken.WaitHandle
时才需要处理,即使这样,计时器在启动时也会自动清理,大多数人也不需要处理互斥锁(因为这样做通常会引入竞争)。它有点像
Task.Dispose
:它在API中,但在API中大部分时间都没有被调用practice@canton7问题在于
任务.Dispose
明确指出:“但是,特别是如果您的应用程序针对.NET Framework 4.5或更高版本,则无需调用Dispose,除非性能或可伸缩性测试表明,根据您的使用模式,您的应用程序的性能将通过处理任务而得到改善。“。文档中没有关于
CancellationTokenSource.Dispose
方法的这些细节!我说这“有点像”
任务。Dispose
。尽管是API的一部分,但有很多类型的处理在实践中通常是不必要的,不管文档怎么说。CTS和互斥体一样,通常很讨厌正确地进行处理,因为除了极少数情况外,实际上并不需要进行处理,所以一般的惯例是不麻烦的。@canton7在这种情况下,该方法的文档似乎是错误的,应该使用“Always”等措辞不太强硬的语言更新文档。否则,我们应该停止一般的信任吗?总是带着一撮盐去看MSDN文档!它们很好,而且越来越好,但并不完美。
CancellationToken capturedToken = default;
var subscription = Observable.FromAsync(async token =>
{
    capturedToken = token;
    token.Register(() => Console.WriteLine("Token canceled"));
    await Task.Delay(Timeout.Infinite, token);
})
.TakeUntil(Observable.Timer(TimeSpan.FromMilliseconds(500)))
.Finally(() => Console.WriteLine("The observable was terminated"))
.Subscribe();

Thread.Sleep(1000);

var cts = (CancellationTokenSource)(typeof(CancellationToken)
    .GetField("_source", BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(capturedToken));
bool disposed = (bool)(typeof(CancellationTokenSource)
    .GetField("_disposed", BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(cts));
Console.WriteLine($"IsCancellationRequested: {cts.IsCancellationRequested}");
Console.WriteLine($"IsDisposed: {disposed}");