我有以下一些代码来设置我的Rx连接:
事件相关定义:
public class QueryEventArgs : EventArgs
{
public SomeParametersType SomeParameters
{
get;
set;
}
public object QueryContext
{
get;
set;
}
};
public delegate void QueryDelegate(object sender, QueryEventArgs e);
public event QueryDelegate QueryEvent;
初始化:
queryObservable = Observable.FromEvent<QueryEventArgs>(this, "QueryEvent");
queryObservable.Subscribe((e) =>
{
tbQueryProgress.Text = "Querying... ";
client.QueryAsync(e.EventArgs.SomeParameters, e.EventArgs.QueryContext);
});
queryCompletedObservable = from e in Observable.FromEvent<QueryCompletedEventArgs>(client, "QueryCompleted").TakeUntil(queryObservable) select e;
queryCompletedObservable.Subscribe((e) =>
{
tbQueryProgress.Text = "Ready";
SilverlightClientService_QueryCompleted(e.Sender, e.EventArgs);
},
(Exception ex) =>
{
SetError("Query error: " + ex);
}
);
“client”是WCF客户端,其他一切都是不言自明的。
“TakeUntil”用于阻止用户在当前正在运行的新查询中执行新查询时踩踏自己。但是,如果删除“TakeUntil”子句,代码可以正常工作,如果我将其放入,则查询永远不会完成。
这是正确的模式吗?如果是这样,我做错了吗?
干杯, -Tim
答案 0 :(得分:3)
TakeUntil
在从其参数收到值时终止订阅,因此您的第一个queryObservable
启动查询,但也终止对完整事件的订阅。
更简单的解决方案是围绕实际查询设置IObservable
,然后使用Switch
确保一次只运行一个查询。
public static class ClientExtensions
{
public static IObservable<QueryCompletedEventArgs> QueryObservable(
this QueryClient client,
object[] someParameters, object queryContext)
{
return Observable.CreateWithDisposable<QueryCompletedEventArgs>(observer =>
{
var subscription = Observable.FromEvent<QueryCompletedEventArgs>(
h => client.QueryCompleted += h,
h => client.QueryCompleted -= h
)
.Subscribe(observer);
client.QueryAsync(someParameters, queryContext);
return new CompositeDisposable(
subscription,
Disposable.Create(() => client.Abort())
);
});
}
}
然后你可以这样做:
queryObservable = Observable.FromEvent<QueryEventArgs>(this, "QueryEvent");
queryObservable
.Select(query => client.QueryObservable(
query.EventArgs.SomeParameters,
query.EventArgs.QueryContext
))
.Switch()
.Subscribe(queryComplete =>
{
tbQueryProgress.Text = "Ready";
// ... etc
});
这将设置一个连续流,每个“Query”事件启动一个查询,该查询从该查询中发出完整事件。新查询会自动删除先前的查询(如果可能)并开始新的查询。