I do not agree with your question.
The problem is not your await . But your Task.Run . Actually there should not be await Task.Run for you ASP.Net code. The effect of this is an unnecessary thread switch. Since you do not have STA threads in ASP.Net, there is no need for this, and it just slows down your code.
If you stick to real threads without Task , you shouldn't have any problems, as you will remain in one thread. If your application server does not have a very limited number of clients and has a huge number of processor-bound operations, multithreading is bad for scaling, since one user can quickly fill out your server’s schedule.
You really should use Task.FromResult or TaskCompletionSource.Task to make sure that you remain single-threaded. Which, by the way, will fix your problem using the [ThreadLocal] properties.
TL: DR
Do not use Task.Run on your server side. Use Task.FromResult so that you have only one thread.
EDIT: answer
Which stream? On the client side, you will still use await . I never said do not use await . I said that DO NOT use await directly with Task.Run (except for the UI thread). I did not say that you should LOCK the thread. Since your thread must do WORK to get the result you pass to Task.FromResult . LOCK means that the thread does nothing, consuming resources (namely, memory). Damn it doesn't even have to
The server side should use this template:
public ExampleService : IExampleService { public Task<string> GetUsernameAsync() { var name = System.Threading.Thread.CurrentPrincipal.Name; return Task.FromResult(name); } }
customer must stay
public ExampleController { public async Task<ActionResult> Index() { using(var serviceClient = ServiceFactory.GetServiceClient()) using(Security.Impersonation.Impersonate()) { var data = await serviceClient.GetUsernameAsync(); return View(data); } } }
and in the case when your ServiceClient is resolved locally, everything is done synchronously (faster and with less resources). The point here is that you are using the Task async pattern for the Thread Style in async. Task.Run is aync concurrency style and should be used only when you need to use a different thread (either because you are attached to the processor, or ONLY THESE NEEDS that will be used for something else).