Domanda

Sto usando i dataservices ADO.NET in un'applicazione Silverlight e poiché le librerie silverlight non supportano la chiamata ToList () su IQueryable, ho pensato che fosse possibile creare un metodo di estensione attorno a questo chiamato SilverlightToList (). Quindi in questo metodo sto chiamando il metodo BeginExecute sul mio contesto come mostrato di seguito:

            var result = context.BeginExecute<T>(currentRequestUri,null,context);
            result.AsyncWaitHandle.WaitOne();
            return context.EndExecute<T>(result).ToList();

Il problema è che quando chiamo il metodo WaitOne () questo provoca un deadlock. È una limitazione dei servizi dati ADO.NET in Silverlight? C'è forse una soluzione alternativa per questo?

È stato utile?

Soluzione 2

Da allora ho trovato questo post sul forum MSDN che dice che qualsiasi gestito - > UnManaged - > Il marshalling gestito avviene sul thread dell'interfaccia utente, il che spiega perché la chiamata del metodo WaitOne è in sospeso ...

Altri suggerimenti

Sono riuscito a sconfiggere (: P) il mostro asincrono in Silverlight in questo modo:

var ctx = new ModelEntities(new Uri("http://localhost:2115/Data.svc"));

ManualResetEvent m1 = new ManualResetEvent(false);
ManualResetEvent m2 = new ManualResetEvent(false);

var q1 = (DataServiceQuery<Department>)(from e in ctx.Department select e);
var q2 = (DataServiceQuery<Person>)(from e in ctx.Person select e);

Department[] r1 = null;
Person[] r2 = null;

q1.BeginExecute(r =>
{
    try { r1 = q1.EndExecute(r).ToArray(); }
    finally { m1.Set(); }
}, null);
q2.BeginExecute(r =>
{
    try { r2 = q2.EndExecute(r).ToArray(); }
    finally { m2.Set(); }
}, null);

ThreadPool.QueueUserWorkItem((o) =>
{
    WaitHandle.WaitAll(new WaitHandle[] { m1, m2 });
    // do your thing..
});

L'ideea di base è generare un thread del cameriere (l'ultimo blocco) che avrebbe riferimenti agli oggetti wait. NON inserire la chiamata WaitAll nel metodo / thread del chiamante perché ciò comporterà un deadlock come altri precedentemente menzionati su questo sito o altri siti.

Il deadlock si verifica perché i thread non si avviano fino alla fine del metodo e il metodo non termina perché la chiamata WaitAll attende la fine dei thread figlio.

Non nel mio caso sopra però perché WaitAll è su UN ALTRO thread.

PS: Invece del // fai il tuo codice di posizione della linea di cose che utilizza i riferimenti acquisiti r1 e r2 che conterranno i dati o null se quel risultato non è riuscito.

Probabilmente a Silverlight non piacerà nulla di sincrono, perché è progettato per essere eseguito nel browser e può avere solo un thread con cui giocare - e deve condividerlo. E l'unico thread disponibile per l'host è quello fornito dal browser.

Tutte le chiamate di servizio in Silverlight devono essere asincrone. Quindi devi definire un callback per ottenere il risultato - in questo modo:

context.BeginExecute<T>(currentRequestUri, resultCallback, context);

private void resultCallback(IAsyncResult asyncResult)
{
    DataServiceContext context = asyncResult.AsyncState as DataServiceContext;
    var result = context.EndExecute<T>(asyncResult);
    // Do whatever you need with the result here
}

Ecco un buon riferimento a MSDN: http://msdn.microsoft.com/en- us / library / cc838191 (VS.95) aspx

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top