首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IObservable -替换AutoResetEvent

IObservable -替换AutoResetEvent
EN

Stack Overflow用户
提问于 2011-03-03 02:47:04
回答 2查看 403关注 0票数 1

只是想知道如何才能替换下面的AutoResetEvent?我试着思考如何用RX的方式或任务来做这件事,但我知道怎么做。

代码语言:javascript
复制
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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-03 03:29:05

考虑像这样构造代码:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2011-03-03 03:42:41

我会让这个方法返回一个IObservable<LogOnResponse>,这样你就不需要等到准备好返回的时候了。您还必须注意竞争条件,因为您的登录呼叫可能会在您有机会订阅之前完成。这样的代码应该可以处理竞争条件,并通过返回的IObservable返回响应。很明显,你可以订阅它,一旦LogOnResponse出现,你就可以得到它。

代码语言:javascript
复制
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。只有在您订阅之后,才会调用实际的登录。

代码语言:javascript
复制
// Gets the IObservable<LogOnResult>
var logonResponseAsObservable = LogOn(); 
//Execute the logon and wait for a response asynchronously
logonResponseAsObservable.Subscribe(response => HandleLogOnResponse(response)); 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5171922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档