我想知道如何替换下面的AutoResetEvent?我试图考虑如何使用RX方式或任务,但我可以看到如何做到这一点。
public void LogOnResponse LogOn()
{
LogOnResponse logOnResponse = null;
var waitEvent = new AutoResetEvent(false);
var listener = _connection.LoginStatusEvent
.Where(x => x.LoginState == LoginState.LoggedOn
|| x.LoginState == LoginState.LoggedRejected);
listener.Subscribe(x => {
logOnResponse = new LogOnResponse();
logOnResponse.InformationMessage = x.Message;
logOnResponse.IsAuthenticated = x.LoginState == LoginState.LoggedOn;
waitEvent.Set();
});
connection.Login(connectionInfo);
waitEvent.WaitOne(2000);
return logOnResponse;
}
答案 0 :(得分:1)
考虑如下构造代码:
var listener = _velocityConnection.LoginStatusEvent
.Where(x => x.LoginState == LoginState.LoggedOn || x.LoginState == LoginState.LoggedRejected);
var logOnResponse = listener.Select(x =>
new LogOnResponse() {
logOnResponse.InformationMessage = x.Message;
logOnResponse.IsAuthenticated = x.LoginState == LoginState.LoggedOn;
}
).Timeout(TimeSpan.FromSeconds(2), Observable.Return(new LogOnResponse() {...}))
.Publish()
.RefCount();
connection.Login(connectionInfo);
return logOnResponse.First();
我们使用Publish
来执行顺序无关紧要,而RefCount()隐藏ConnectableObservable
答案 1 :(得分:0)
我的方法会返回IObservable<LogOnResponse>
,因此您无需等到准备好返回。您还需要注意竞争条件,因为您可以在有机会订阅之前完成对Login的调用。这样的事情应该处理竞争条件并通过返回的IObservable返回响应。然后,您可以明显订阅此内容,以便在它出现后立即获取LogOnResponse。
public IObservable<LogOnResponse> LogOn()
{
return Observable.CreateWithDisposable<LogOnResponse>(observer =>
{
var loginDisposable = _velocityConnection.LoginStatusEvent
.Where(x => x.LoginState == LoginState.LoggedOn
|| x.LoginState == LoginState.LoggedRejected)
.Select(x => {
logOnResponse = new LogOnResponse();
logOnResponse.InformationMessage = x.Message;
logOnResponse.IsAuthenticated = x.LoginState == LoginState.LoggedOn;
return logOnResponse;
}).Take(1).Subscribe(observer);
connection.Login(connectionInfo);
return loginDisposable;
});
}
这里要注意的一件事是调用此方法只返回IObservable。在您订阅之前,不会调用实际登录。
// Gets the IObservable<LogOnResult>
var logonResponseAsObservable = LogOn();
//Execute the logon and wait for a response asynchronously
logonResponseAsObservable.Subscribe(response => HandleLogOnResponse(response));