Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 253 Vote(s) - 3.57 Average
  • 1
  • 2
  • 3
  • 4
  • 5
AspNetSynchronizationContext

#1
Trying to use new C# 5 async model it was surprising to me `AspNetSynchronizationContext` is an internal class (as well as `AspNetSynchronizationContextBase` base). Thus undocumented. But it's essential to know what it does when utilizing async/await feature within your ASP.NET code. Am I correct that
It **does** guarantee your continuations will get the same `HttpContext.Current` as original callers?
It **does not** guarantee the continuations will execute on the same thread as the callers?

If the latter assumption is not true and I get the original thread can I be sure to get the same thread context in continuations? I mean principal/culture associated with the thread and thread local storage? That's important because ASP.NET localization relies on thread's culture and my application relies on .NET role security model (thread's principal).
Reply

#2
> Am I correct that It does guarantee your continuations will get the same HttpContext.Current as original callers? It does not guarantee the continuations will execute on the same thread as the callers?

Yes, `HttpContext.Current` is preserved, and yes, the continuations may execute on a different thread.

> I mean principal/culture associated with the thread and thread local storage? That's important because ASP.NET localization relies on thread's culture and my application relies on .NET role security model (thread's principal).

Ordinary thread-local storage is lost. You can mitigate this by using `LogicalCallContext` (which flows with `ExecutionContext`), but with `async` it's easier to just reference the variables directly.

Principal is always preserved; to do otherwise would be a security risk. This flows with `ExecutionContext`.

I believe that culture flows with `AspNetSynchronizationContext`, but I haven't tested this out on [.NET 4.5's new implementation][1].

---

You may find my [MSDN article on `SynchronizationContext`][2] helpful. It's not official documentation (I don't work for Microsoft), but at least it's something. Note that the `AspNetSynchronizationContext` referenced in that article is now called `LegacyAspNetSynchronizationContext` in .NET 4.5.

Another great resource is Stephen Toub's [`ExecutionContext` vs. `SynchronizationContext`][3].


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

Reply

#3
Well, while capturing the ExecutionContext is always guaranteed, capturing and running the execution on the same SynchronizationContext depends on the Awaiter.

The most common awaiter (the type returned by GetAwaiter() method that's internally called when you "await" something) is TaskAwaiter that returned by Task.GetAwaiter(). By default, TaskAwaiter **will capture the current SynchronizationContext and run the continuation delegate on the captured SynchronizationContext**. Which means, you'll be able to use HttpContext.Current in the rest of your method, and you don't mind that it'll run as a continuation. So, this code will works as expected (the part where you writes "B" will run on the same synchronizationcontext as the first line):

HttpContext.Current.Response.Write("A");
await Task.Delay(1000);
HttpContext.Current.Response.Write("B")

You can change this behavior by using `Task.ConfigureAwait(false)` method, that tells the awaiter to not marshal the rest of the method back to the original SynchronizationContext.

Of course, if you use Task.Run or Task.Factory.StartNew in the async method you're calling, it's your responsibility to capture the SynchronizationContext again.


Best of luck.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through