在过去的3-4个月里,我发现,默认情况下或者只是巧合,我的所有RxUI可观察量(.Subscribe)都是在各种对象中创建的。构造函数(代码)。但是,该应用程序还大量使用监视各种流并执行操作(更新UI,创建事务等)的后台任务,有时,这些任务需要中止某些事务。所以,我只是想知道哪里最好的地方'实例化一个听众'中止指令(旗帜)?在交易对象中创建或在“监督”范围内。监控流的对象?如果在交易中,对业绩和处置有何影响?我知道这是一个相当广泛的问题,但我希望有人可以推荐一个合适的模式。任何指针,评论赞赏。
请参阅下面的模拟代码:
using System;
using System.Threading.Tasks;
using System.Threading;
using ReactiveUI;
using UserSettingsClassLibrary;
namespace fxR.UTILITIES.MockCode
{
public class MockRxUI_AbortTransaction : ReactiveObject { } // ignore this class
public class ManageTransactions : ReactiveObject
{
// properties
CancellationTokenSource ctTransactionPosition;
// constructor
public ManageTransactions()
{
// initialise
ctTransactionPosition = new CancellationTokenSource();
}
// methods
public async Task OpenTransaction(MyStreamProcessingObject sPO, string user, string openTransactionAction)
{
// ... create transaction object, db log, etc
// open a 'listener' in case this Transaction is aborted
if (user.Contains("/"))
{
sPO.WhenAnyValue(x => x.ActiveObject.AbortTrade)
.Log(this, "TransactionOpen -> Abort trigger ")
.Subscribe(abort =>
{
if (sPO.ActiveObject.TradeOpen && abort)
{
// abort
}
});
}
}
}
// the OpenTransaction method above would be called from elsewhere in the app, eg
public class SomeOtherObject : ReactiveObject
{
ManageTransactions _manageTransactions;
MyStreamProcessingObject _sPO;
public SomeOtherObject(MyStreamProcessingObject sPO)
{
_sPO = sPO;
_manageTransactions = new ManageTransactions();
}
public async Task DoSomethingAsync()
{
await _manageTransactions.OpenTransaction(_sPO, Environment.UserName + "/" + GetType().Name, "TransactionAction").ConfigureAwait(false);
}
}
// ================================================================================================
// OR, open a 'listener' on the Stream Processing Object when it is constructed (first initialised)
// ================================================================================================
public class MyStreamProcessingObject : ReactiveObject
{
// object properties
private ActiveObject _activeObject;
public ActiveObject ActiveObject
{
get { return _activeObject; }
set { this.RaiseAndSetIfChanged(ref _activeObject, value); }
}
// constructor
public MyStreamProcessingObject()
{
// listen for Transaction abort status
this.WhenAnyValue(x => x.ActiveObject.AbortTrade)
.Log(this, "Log -> ActiveObject.AbortTransaction")
.Subscribe(async abort =>
{
if (abort)
{
await Task.Run(async () => await AbortOpenAutoTransaction().ConfigureAwait(false));
}
});
}
// methods
private async Task AbortOpenAutoTransaction()
{
var ok = false;
// await some abort code, if all ok, set ok = true;
if (ok) ActiveObject.AbortTrade = false;
}
}
}
答案 0 :(得分:0)
我可以在async/await
之前就订阅和一次性用品给你一些建议。您可以使用以下模式。
async Task<int> Foo(IObservable<bool> observable, Task<int> task){
var subscription = observable.Subscribe
( x => Console.WriteLine("WhooHoo");
using(subscription)
{
var value = await task;
return value + 10;
}
}
相当于
async Task<int> Foo(IObservable<bool> observable, Task<int> task){
var subscription = observable.Subscribe
( x => Console.WriteLine("WhooHoo");
try
{
var value = await task;
return value + 10;
}finally{
subscription.Dispose();
}
}
任务完成后,将处理订阅。
但是,如果您发现在构造函数中创建订阅,那么您需要另一种模式。
public class Foo : ReactiveObject, IDisposable {
private CompositeDisposable _Cleanup = new CompositeDisposable();
public Foo(IObservable<int> observable){
var subscription = observable
.Subscribe(x=>Console.WriteLine("WhooHoo"));
_Cleanup.Add(subscription);
}
public void Dispose(){
_Cleanup.Dispose();
}
}
或更好地使用RXUI扩展方法DisposeWith
public class Foo : ReactiveObject, IDisposable {
private CompositeDisposable _Cleanup = new CompositeDisposable();
public Foo(IObservable<int> observable){
observable
.Subscribe(x=>Console.WriteLine("WhooHoo"))
.DisposeWith(_Cleanup);
}
public void Dispose(){
_Cleanup.Dispose();
}
}
通常我会创建一个基类
public class DisposableReactiveObject : ReactiveObject, IDisposable {
protected CompositeDisposable Cleanup { get; } = new CompositeDisposable;
public void Dispose(){
_Cleanup.Dispose();
}
}
然后可以将其用作
public class Foo : DisposableReactiveObject {
public Foo(IObservable<int> observable){
observable
.Subscribe(x=>Console.WriteLine("WhooHoo"))
.DisposeWith(Cleanup);
}
}