是否可以將 Rx.Net 中的 Using 運算子與實作IAsyncDisposable而不是的資源一起使用IDisposable?如果沒有,我可以使用某種解決方法嗎?
uj5u.com熱心網友回復:
這是一個Using適用于IAsyncDisposable物件的方法:
/// <summary>
/// Constructs an observable sequence that depends on a resource object,
/// whose lifetime is tied to the resulting observable sequence's lifetime.
/// </summary>
public static IObservable<TResult> Using<TResult, TResource>(
Func<TResource> resourceFactory,
Func<TResource, IObservable<TResult>> observableFactory)
where TResource : IAsyncDisposable
{
return Observable.Defer(() =>
{
TResource resource = resourceFactory();
IObservable<TResult> observable;
try { observable = observableFactory(resource); }
catch (Exception ex) { observable = Observable.Throw<TResult>(ex); }
Lazy<Task> lazyDisposeTask = new(() => resource.DisposeAsync().AsTask());
IObservable<TResult> disposer = Observable
.FromAsync(() => lazyDisposeTask.Value)
.Select(_ => default(TResult))
.IgnoreElements();
return observable
.Catch((Exception ex) => disposer.Concat(Observable.Throw<TResult>(ex)))
.Concat(disposer)
.Finally(() => lazyDisposeTask.Value.GetAwaiter().GetResult());
});
}
此方法與 Rx 方法具有相同的簽名Observable.Using(除了where子句),并且可以以相同的方式使用。
此實作處理所有完成情況:
- 成功完成:
IAsyncDisposable資源被Concat操作者異步處理。 - 錯誤完成:
IAsyncDisposable資源由Catch操作員異步處理。 - 序列在完成之前被取消訂閱:
IAsyncDisposable資源由Finally操作員同步處理。在這種情況下,異步處理資源是不可能的,原因 最后">在這里解釋。
異步工廠方法的變體:
public static IObservable<TResult> Using<TResult, TResource>(
Func<CancellationToken, Task<TResource>> resourceFactoryAsync,
Func<TResource, CancellationToken, Task<IObservable<TResult>>> observableFactoryAsync)
where TResource : IAsyncDisposable
{
return Observable.Create<TResult>(async (observer, cancellationToken) =>
{
TResource resource = await resourceFactoryAsync(cancellationToken);
IObservable<TResult> observable;
try { observable = await observableFactoryAsync(resource, cancellationToken); }
catch { await resource.DisposeAsync(); throw; }
Lazy<Task> lazyDisposeTask = new(() => resource.DisposeAsync().AsTask());
IObservable<TResult> disposer = Observable
.FromAsync(() => lazyDisposeTask.Value)
.Select(_ => default(TResult))
.IgnoreElements();
return observable
.Catch((Exception ex) => disposer.Concat(Observable.Throw<TResult>(ex)))
.Concat(disposer)
.Finally(() => lazyDisposeTask.Value.GetAwaiter().GetResult())
.Subscribe(observer);
});
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/344046.html
上一篇:如何讓VS2019不為構建專案創建檔案夾“net5.0”?
下一篇:嘗試激活服務時無法決議型別“System.Lazy`1[System.Net.Http.IHttpClientFactory]”的服務
