Pergunta

I came up with an idea on how to fake SL WCF support for synchronous calls.

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.

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.

/*edit: actually, thinking about it, it queues the callback on the ui thread, which is waiting. this is also the reason we don't have to Dispatcher.Invoke when we get the results. 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?

Foi útil?

Solução

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. 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.

When developing in a SIlverlight environment you need to be able to program asynchronously, rather than using synchronous methods. 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top