2012-11-02 10 views
11

Sto chiamando un servizio WCF da un'app WinRT. Il servizio richiede che alcune intestazioni siano impostate per l'autenticazione. Il problema è che se faccio più chiamate al servizio simultaneamente, ottengo la seguente eccezione:Chiamate di client WCF asincroni con intestazioni personalizzate: questo OperationContextScope viene eliminato dall'ordine

Questo OperationContextScope sia disposta fuori ordine.

Il codice attuale è simile al seguente:

public async Task<Result> CallServerAsync() 
{ 
    var address = new EndpointAddress(url); 
    var client = new AdminServiceClient(endpointConfig, address); 

    using (new OperationContextScope(client.InnerChannel)) 
    { 
     OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = GetHeader(); 

     var request = new MyRequest(...); 
     { 
      context = context, 
     }; 

     var result = await client.GetDataFromServerAsync(request); 
    } 
} 

ho trovato il seguente commento from the docs:

Non utilizzare l'asincrona “attendere” modello all'interno di un blocco OperationContextScope. Quando si verifica la continuazione, può essere eseguito su un thread diverso e OperationContextScope è thread specifico. Se è necessario chiamare "attendere" per una chiamata asincrona, utilizzarla al di fuori del blocco OperationContextScope.

Quindi sembra che io stia chiaramente chiamando il servizio in modo errato. Ma qual è il modo corretto?

risposta

4

Tutto sembra funzionare abbastanza bene con il seguente codice:

public async void TestMethod() 
{ 
    var result = await CallServerAsync(); 
} 

public Task<Result> CallServerAsync() 
{ 
    var address = new EndpointAddress(url); 
    var client = new AdminServiceClient(endpointConfig, address); 

    using (new OperationContextScope(client.InnerChannel)) 
    { 
     OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = GetHeader(); 

     var request = new MyRequest(...); 
     { 
      context = context, 
     }; 

     return client.GetDataFromServerAsync(request); 
    } 
} 
+2

Questo potrebbe funzionare, ma funzionerà per caso. Poiché non si attende la chiamata GetDataFromServerAsync, il thread-switch non si verificherà. L'ambito di contesto dell'operazione è già disponibile prima che la chiamata sia effettivamente completata. Il motivo per cui funziona è probabilmente perché l'intestazione in uscita viene aggiunta prima che la chiamata interna sia attesa internamente. –

+0

È possibile attendere l'attività GetDataFromServerAsync restituisce subito dopo la fine del blocco using (assegnare l'attività a una variabile). –

Problemi correlati