1

以下の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;
}
4

2 に答える 2

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

于 2011-03-02T19:29:04.803 に答える
0

メソッドを返すIObservable<LogOnResponse>ようにしますので、戻る準備ができるまで待つ必要はありません。また、サブスクライブする前にログインへの呼び出しが完了する可能性があるため、競合状態に注意する必要があります。このようなものは、競合状態を処理し、返された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;
   });
}

ここで注意すべきことの1つは、このメソッドを呼び出すとIObservableのみが返されることです。サブスクライブするまで、実際のログインは呼び出されません。

// Gets the IObservable<LogOnResult>
var logonResponseAsObservable = LogOn(); 
//Execute the logon and wait for a response asynchronously
logonResponseAsObservable.Subscribe(response => HandleLogOnResponse(response)); 
于 2011-03-02T19:42:41.377 に答える