Silverlight WCF中的异步回调线程锁定

时间:2013-02-10 01:52:55

标签: c# wcf silverlight iasyncresult

我想出了如何伪造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的原因。无论如何,我总是可以在专用线程中执行整个操作(需要等待),然后在那里等待,但这需要一堆重构,避免尝试这一点。 * /

有什么方法吗?

1 个答案:

答案 0 :(得分:1)

这种情况的原因是EndExecute方法会封送到UI线程,但是您通过Sleep调用阻止了UI线程。使用什么技术来阻塞线程并不重要,只要在UI线程中调用该方法,你所做的任何事都会导致死锁。

在SIlverlight环境中开发时,您需要能够异步编程,而不是使用同步方法。如果您使用的是C#5.0,则可以使用async / await功能,它允许您编写出现同步的异步代码,但它将被编译为使用回调/延续的异步调用,这就是你如果您尚未升级到该版本,则需要执行此操作。