Ein Async-Dienst, der async-await verwendet, reagiert sehr schnell, da er viele Client-Aufrufe verschachteln und parallel ausführen kann (2). Trotzdem kann der Dienst vollständig threadsicher auf einem Thread (3) ausgeführt werden und kann ein Singleton-Dienst (1) oder ein Dienstobjekt sein, das von dem Framework für eine Sitzung oder einen Aufruf nur erstellt wird.
, wenn der Dienst der Umsetzung beachten Sie bitte die ServiceBehaviourAttributes (1) ... (3):
[ServiceContract(Namespace="X", Name="TheContract")]
public interface IAsyncContractForClientAndService
{
[OperationContract]
Task<TResponse> SendReceiveAsync(TRequest req);
}
[ServiceBehavior (InstanceContextMode = InstanceContextMode.Single, // (1)
// also works with InstanceContextMode.PerSession or PerCall
ConcurrencyMode = ConcurrencyMode.Multiple, // (2)
UseSynchronizationContext = true)] // (3)
public MyService : IAsyncContractForClientAndService
{
public async Task<TResponse> SendReceiveAsync(TRequest req)
{
DoSomethingSynchronous();
await SomethingAsynchronous();
// await lets other clients call the service here or at any await in
// subfunctions. Calls from clients execute 'interleaved'.
return new TResponse(...);
}
}
Um jeden Anruf auf einem Thread laufen, ein System.Threading.SynchronizationContext.Current = null muss! vorhanden sein, wenn Sie den ServiceHost öffnen(). Mit dem SynchronizationContext müssen Sie sich nicht um Sperren kümmern. Atomare, nicht unterbrechbare Codeabschnitte erstrecken sich grob von einem Warten zum nächsten. Achten Sie darauf, dass die Daten des gemeinsam genutzten Dienstes bei jedem Warten in einem konsistenten Zustand sind, und beachten Sie, dass aufeinander folgende Anfragen von einem Client nicht in der Reihenfolge beantwortet werden können, in der sie gesendet wurden.
Auf Client-Seite, die asynchrone Service-Betrieb ist awaitable:
var response = await client.Channel.SendReceiveAsync(request);
Es ist nicht möglich aus oder ref Parameter im Betrieb Vertrag zu verwenden. Alle Antwortdaten müssen mit dem zurückgegebenen Wert Task (T) übergeben werden.
Ich benutze diese Schnittstelle in AsyncWcfLib, unterstützt eine Actor based programming model.
Corr. +1 einfach, um mich etwas Glänzendes und Neues vorzustellen. – spender