[英]Observable.Using disposes on other thread than created on
我有一個ASP.NET WebApi請求方法,該方法反過來使用Observable.Using
在舊版資源上啟動異步調用。 此資源將產生一個新線程,在該線程上引發事件,然后將事件轉換為資源周圍的包裝程序公開的IObservable
流中的OnNext
項目。
我正在使用IObservable.FirstOrDefaultAsync()
await
流的結果,並且我的WebApi方法被標記為async
。
如果我使用這個設置,我會聲名狼藉
異步模塊或處理程序在異步操作仍掛起的同時完成
所以,我的第一個問題是關於此的。 我想得到這個是因為遺留資源產生了新的異步操作(沒有async
/ await
),但是ASP.NET到底是怎么知道的呢? 已經注冊了什么? 我發現ASP.NET正在查看SynchronizationContext.Current._state.VoidAsyncOutstandingOperationCount
來引發此異常,但是哪個調用會遞增此屬性? 線程排隊到ThreadPool? 我相當確定這是由舊資源造成的。
現在,當我處理資源時,為什么這些操作仍然進行? 好吧,似乎Dispose
運行在傳播事件的線程上,其概念類似於以下代碼片段。
Observable
.Using(
() => {
Console.WriteLine($"Created on thread: {Thread.CurrentThread.ManagedThreadId}");
return Disposable.Create(() => {
Console.WriteLine($"Disposed on thread: {Thread.CurrentThread.ManagedThreadId}");
});
},
_ => Observable.Return(1, NewThreadScheduler.Default))
.Do(_ => Console.WriteLine($"OnNext on thread: {Thread.CurrentThread.ManagedThreadId}"))
.Wait();
結果類似於:
Created on thread: 10
OnNext on thread: 11
Disposed on thread: 11
這是設計使然嗎? 當使用using
來配置資源時,很明顯,由於代碼是同步的,因此該資源被配置在創建它的同一線程上。 當Dispose
在單獨的線程上運行時,調用代碼將繼續運行,並且控制器將在Dispose
完全完成之前(至少在大多數情況下)返回。
我該如何以合理的方式緩解這種情況? 似乎可行的一種方法是,不使用Observable.Using
,而是使用返回給控制器的此構造,使用FirstOrDefaultAsync()
await
它:
var resource = // Creating resource manually.
return resource.StartAsyncOperation() // <- observable producing events
.ObserveOn(SynchronizationContext.Current)
.Do(_ => resource.Dispose());
不過,這對我來說就像是駭客。
有什么想法和建議嗎?
我想我在這里面臨的問題之一是,當我使用Observable.Using
時,在序列終止/完成之后調用資源的Dispose
方法。 應該是這樣嗎? 在那種情況下,實際上沒有辦法等待使用該構造的Dispose
。 我必須使用其他IObservable<Unit> Disposed()
方法或類似方法來修改api ...
Dispose
將在調用它的線程上調用(嗯)。 更有用的是,在另一個線程上消耗/觀察Rx序列時,將在該線程上調用OnComplete
回調。 如果將Rx與標准運算符一起使用,則當序列終止時(使用OnError
或OnComplete
),您將獲得自動處置行為。 自動處理將僅在OnComplete
/ OnError
之后立即發生,並且將在同一線程上運行。
如果您希望將處置綁定到調度程序,則建議查看System.Reactive.Disposables.ScheduledDisposable
類型。 但是,似乎在這里使用SynchronizationContext
更自然,因此在這種情況下, System.Reactive.Disposables.ContextDisposable
可能更合適。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.