0

我正在编写一个简单的 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变量),然后在以后的代码中使用。

4

2 回答 2

1

这比 Rx更适合async/关键字。awaitRx 主要用于管理数据流,而在这种情况下,您要做的就是同步管理异步调用。您可以尝试像这样使用 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

于 2013-03-23T12:37:12.023 回答
0

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

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

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

于 2013-03-23T06:25:48.477 回答