简体   繁体   English

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

[英]Async callback thread lock in Silverlight WCF

I came up with an idea on how to fake SL WCF support for synchronous calls. 我想出了一个关于如何假冒对同步调用的SL WCF支持的想法。

Basically, 基本上,

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;
}

What happens is that this loops forever. 发生的事情是,这将永远循环。

I put a break-point on the while loop, move it out of it and resume execution, and in the very next millisecond the results arrive. 我在while循环上放置了一个断点,将其移出循环并继续执行,然后在接下来的一毫秒内结果到达。

So, I am thinking the callback for the query to receive the results gets queued to the same thread the query was invoked in. 因此,我在考虑查询接收结果的回调被排队到调用查询的同一线程中。

SL seems very determined to maintain this behavior, so even if I wrap the myQuery.BeginExecute in a new thread, I still get the same behavior. SL似乎非常决心保持这种行为,因此即使我将myQuery.BeginExecute包装在新线程中,我仍然会得到相同的行为。

/*edit: actually, thinking about it, it queues the callback on the ui thread, which is waiting. / * edit:实际上,考虑到它,它会将回调在等待的ui线程上排队。 this is also the reason we don't have to Dispatcher.Invoke when we get the results. 这也是我们不必Dispatcher.Invoke的原因。当我们得到结果时调用。 anyhow, I can always do the whole operation (that requires the wait) in a dedicated thread, and then wait there, but this will require a bunch of refactoring, avoiding which is the point of trying this. 无论如何,我总是可以在专用线程中执行整个操作(需要等待),然后在那里等待,但这将需要大量的重构,避免尝试这一点。 */ * /

Is there any way around this? 有没有办法解决?

The reason this hangs is that the EndExecute method marshals to the UI thread, but you're blocking the UI thread with your Sleep call. 挂起的原因是EndExecute方法封送至UI线程,但您使用Sleep调用阻塞了UI线程。 It doesn't matter what technique you use to block the thread, anything you do is going to be causing a deadlock given that the method is called in a UI thread. 不管使用哪种技术来阻塞线程都没有关系,考虑到在UI线程中调用该方法,您所做的任何事情都会导致死锁。

When developing in a SIlverlight environment you need to be able to program asynchronously, rather than using synchronous methods. 在SIlverlight环境中进行开发时,您需要能够异步编程,而不是使用同步方法。 If you are using C# 5.0 you can use the async/await functionality, which lets you write asynchronous code that appears synchronous, but it will be compiled into asynchronous calls that utilize callbacks/continuations, which is what you would need to do if you have not yet upgraded to that version. 如果您使用的是C#5.0,则可以使用async / await功能,该功能可以让您编写看似同步的异步代码,但是它将被编译为利用回调/继续的异步调用,如果有的话,您将需要执行此操作。尚未升级到该版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM