我正在编写一个简单的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 变量),然后在以后的代码中使用。
答案 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或等待,但尝试是我们学习的方式!