0

我想出了一个关于如何伪造 SL WCF 对同步调用的支持的想法。

基本上,

private _completed;
private IList<Customer> _customers;
public void IList<Customer> GetAllCustomers()
{
    bool completed = false;
    DataServiceQuery<Customer> myQuery = this.Context.Customers;
    myQuery.BeginExecute(OnQueryExecuted, myQuery);

    while (!_completed)
      System.Threading.Thread.Sleep(67); //tried join also

    return _customers;
}

private void OnQueryExecuted(IAsyncResult result)
{
     var query = result.AsyncState as DataServiceQuery<Customer>;
    _customers = query.EndExecute(result).ToList();
    _isCompleted = true;
}

发生的事情是这永远循环。

我在 while 循环上设置了一个断点,将其移出并恢复执行,然后在下一毫秒结果到达。

因此,我认为用于接收结果的查询的回调将排队到调用查询的同一线程中。

SL 似乎非常坚决地保持这种行为,所以即使我将其包装myQuery.BeginExecute在一个新线程中,我仍然会得到相同的行为。

/*编辑:实际上,考虑一下,它在等待的ui线程上排队回调。Dispatcher.Invoke这也是我们得到结果时不必这样做的原因。无论如何,我总是可以在专用线程中完成整个操作(需要等待),然后在那里等待,但这需要进行大量重构,避免尝试这样做的重点。*/

有没有办法解决?

4

1 回答 1

1

挂起的原因是该EndExecute方法编组到 UI 线程,但您的Sleep调用阻塞了 UI 线程。不管你使用什么技术来阻塞线程,你所做的任何事情都会导致死锁,因为该方法是在 UI 线程中调用的。

在 SIlverlight 环境中开发时,您需要能够异步编程,而不是使用同步方法。如果您使用的是 C# 5.0,您可以使用 async/await 功能,它可以让您编写看起来是同步的异步代码,但它会被编译成利用回调/延续的异步调用,如果您有,您需要这样做尚未升级到该版本。

于 2013-02-10T02:32:16.957 回答