Silverlight:使用Rx从同步方法返回值

时间:2013-03-23 05:35:15

标签: c# wcf silverlight asynchronous system.reactive

我正在编写一个简单的Silverlight应用程序和WCF服务。 我想创建一个返回值的同步方法。 该方法本身从WCF服务调用异步方法。在我调用异步方法之后,我想获取它的值,然后返回发送方。 我听说Rx可以解决这类问题。

这是我的代码:

    private void btnCreate_Click(object sender, RoutedEventArgs e)
    {
        string myResult = getMyBook(txtBookName.Text);
        MessageBox.Show("Result\n" + myResult);
        // myResult will be use for another purpose here..
    }

    // I want this method can be called anywhere, as long as the caller still in the same namespace.
    public string getMyBook(string bookName)
    {
        Servo.ServoClient svc = new ServoClient();
        string returnValue = "";

        var o = Observable.FromEventPattern<GetBookCompletedEventArgs>(svc, "GetBookCompleted");
        o.Subscribe(
            b => returnValue = b.EventArgs.Result
            );

        svc.GetBookAsync(bookName);
        return returnValue;
    }

当我点击btnCreate时, myResult 变量仍为空。这是我的代码有问题吗?或者也许我只是不理解Rx概念?我是Rx的新手。

我的目标是:我需要从异步方法中获取结果( myResult 变量),然后在以后的代码中使用。

2 个答案:

答案 0 :(得分:1)

这比Rx更适合async / await个关键字。 Rx主要用于管理数据流,而在这种情况下,您只需要同步管理异步调用。您可以尝试使用Rx:

public string getMyBook(string bookName)
{
    Servo.ServoClient svc = new ServoClient();
    svc.GetBookAsync(bookName);

    var o = Observable.FromEventPattern<GetBookCompletedEventArgs>(svc, "GetBookCompleted");
    return o.First().EventArgs.Result;
}

但是,如果GetBookAsync在您订阅之前引发了该事件,则该线程将永久阻止。您可以使用.Replay().Connect(),但您应该只使用async / await

答案 1 :(得分:0)

请记住,GetBookAsync会立即返回,并将返回存储在returnvalue中的值。当数据到达时,returnvalue将超出范围,到那时btnCreate将完成。

U可以在GetBookAsync上使用await,以便在继续之前等待数据到达。不要忘记这意味着你还需要方法的异步。

不是一个很好的例子或使用RX或等待,但尝试是我们学习的方式!