我想出了如何伪造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
的原因。无论如何,我总是可以在专用线程中执行整个操作(需要等待),然后在那里等待,但这需要一堆重构,避免尝试这一点。 * /
有什么方法吗?
答案 0 :(得分:1)
这种情况的原因是EndExecute
方法会封送到UI线程,但是您通过Sleep
调用阻止了UI线程。使用什么技术来阻塞线程并不重要,只要在UI线程中调用该方法,你所做的任何事都会导致死锁。
在SIlverlight环境中开发时,您需要能够异步编程,而不是使用同步方法。如果您使用的是C#5.0,则可以使用async / await功能,它允许您编写出现同步的异步代码,但它将被编译为使用回调/延续的异步调用,这就是你如果您尚未升级到该版本,则需要执行此操作。