ASP.NET and ThreadStatic as part of TransactionScope's implementation - asp.net

I was wondering how TransactionScope class works to keep the transaction between different method calls (without the need to pass it as a parameter) and I came to this doubt. I've got two considerations about this question:
1
Looking into TransactionScope's implementation through Telerik JustDecompile, I've found that the current transaction is stored in a ThreadStatic member of the System.Transactions.ContextData class (code below).
internal class ContextData
{
internal TransactionScope CurrentScope;
internal Transaction CurrentTransaction;
internal DefaultComContextState DefaultComContextState;
[ThreadStatic]
private static ContextData staticData;
internal WeakReference WeakDefaultComContext;
internal static ContextData CurrentData
{
get
{
ContextData contextDatum = ContextData.staticData;
if (contextDatum == null)
{
contextDatum = new ContextData();
ContextData.staticData = contextDatum;
}
return contextDatum;
}
}
public ContextData()
{
}
}
The CurrentData property is called by TransactionScope's PushScope() method, and the last one is used by most of the TransactionScope constructors.
private void PushScope()
{
if (!this.interopModeSpecified)
{
this.interopOption = Transaction.InteropMode(this.savedCurrentScope);
}
this.SetCurrent(this.expectedCurrent);
this.threadContextData.CurrentScope = this;
}
public TransactionScope(TransactionScopeOption scopeOption)
{
// ...
this.PushScope();
// ...
}
Ok, I guess I've found how they do that.
2
I've read about how bad is to use ThreadStatic members to store objects within ASP.NET (http://www.hanselman.com/blog/ATaleOfTwoTechniquesTheThreadStaticAttributeAndSystemWebHttpContextCurrentItems.aspx) due the ASP.NET thread switching that might occur, so this data can be lost among the worker threads.
So, it looks like TransactionScope should not work with ASP.NET, right? But as far I have used it on my web applications, I don't remember any problem that I've run into about transaction data being lost.
My question here is "what's the TransactionScope's trick to deal with ASP.NET's thread switching?".
Did I make a superficial analysis on how TransactionScope stores its transaction objects? Or TransactionScope class wasn't made to work with ASP.NET, and I can be considered a lucky guy that never had any pain about it?
Could anyone who knows the "very deep buried secrets" of .NET explain that for me?
Thanks

I believe ASP.NET thread switching happens only in specific situations (involving asych IO operations) and early in the request life cycle. Typically, once the control is passed to the actual http handler (for example, Page), thread does not get switched. I believe that in most of situation, transaction scope will get initialized only after that (after page_init/load) and should not be an issue.
Here are few links that might interest you:
http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html
http://piers7.blogspot.com/2005/12/log4net-context-problems-with-aspnet.html

Related

How to properly use Task object in .NET

I am working on an ASP .NET MVC 5 application that requires me to use the Task objects that were introduced in .NET 4.0. I am browsing through a few links that give an overview of Task objects. However, I could use a bit of help to check if I am going in the right direction.
Here is the stub that is generated by Visual Studio:
public Task<MyAppUser> FindByNameAsync(string userName) {
throw new System.NotImplementedException();
}
I have written a method called mySearch() that searches through a list. I could use this function for my implementation:
public Task<MyAppUser> FindByNameAsync(string userName) {
MyAppUser val = mySearch(userName);
return Task<MyAppUser>.FromResult<MyAppUser>(val);
}
While this may work, I am thinking I am not really utilizing the Task paradigm properly. Perhaps I can write the code as follows:
public Task<MyAppUser> FindByNameAsync(string userName) {
return Task<MyAppUser>.Factory.StartNew(() => mySearch(userName));
}
As I understand, I am simply returning a delegate as a Task object which the ASP.NET engine will execute as needed.
Am I using the Task paradigm correctly?
Don't ever return a new Task from an XXXAsync method - that's almost the worst thing you can do. In your case, using Task.FromResult is probably the best option (if you are indeed forced to use the XXXAsync methods and if you really don't have asynchronous I/O for the search method). In a web application, it's better to do the whole thing synchronously rather than appearing asynchronous while still taking up a different thread.
The reasoning is simple - asynchronous methods are a great way to conserve resources. Asynchronous I/O doesn't require a thread, so you can afford to reuse the current thread for other work until the data is actually ready. In ASP.NET, the callback will be posted back to a ThreadPool thread, so you've managed to increase your throughput essentially for free.
If you fake the asynchronous method by using Task.FromResult, it's true that this is lost. However, unlike in WinForms or WPF, you're not freezing the GUI, so there's no point in masking the lacking asynchronicity by spawning a new thread.
When you do the faking by using TaskFactory.StartNew or Task.Run, you're only making things worse, essentially - it's true that you release the original thread as with proper async I/O, but you also claim a new thread from the ThreadPool - so you're still blocking one thread, you just added a bunch of extra work for the plumbing.
#Luaan's answer is quite good. I just want to expound on a couple of principles for using async on ASP.NET.
1) Use synchronous method signatures for synchronous work.
I'm not sure why VS is generating an asynchronous stub. Since your mySearch just "searches through a list" (a synchronous operation), then your method should look like this instead:
public MyAppUser FindByName(string userName) {
return mySearch(userName);
}
2) Use async/await for asynchronous work (i.e., anything doing I/O). Do not use Task.Run or (even worse) Task.Factory.StartNew to fake asynchronous work within a request context.
For example, if you needed to search in a database (I/O), then that would be naturally asynchronous, and you should use the asynchronous APIs (e.g., EF6 has asynchronous queries):
public Task<MyAppUser> FindByNameAsync(string userName) {
return dbContext.Users.Where(x => x.Name == userName).FirstAsync();
}
If you're planning to have asynchronous APIs but for now you're just doing test/stub code, then you should use FromResult:
public Task<MyAppUser> FindByNameAsync(string userName) {
return Task.FromResult(mySearch(userName));
}

Is there a thread-safety issue in this ObjectBuilder code?

I suspect a problem with an old version of the ObjectBuilder which once was part of the WCSF Extension project and meanwhile moved into Unity. I am not sure whether I am on the right way or not so I hope someone out there has more competent thread-safety skills to explain whether this could be an issue or not.
I use this (outdated) ObjectBuilder implementation in an ASP.Net WCSF web app and rarely I can see in the logs that the ObjectBuilder is complaining that a particular property of a class cannot be injected for some reason, the problem is always that this property should never been injected at all. Property and class are changing constantly. I traced the code down to a method where a dictionary is used to hold the information whether a property is handled by the ObjectBuilder or not.
My question basically comes down to: Is there a thread-safety issue in the following code which could cause the ObjectBuilder to get inconsistent data from its dictionary?
The class which holds this code (ReflectionStrategy.cs) is created as Singleton, so all requests to my web application use this class to create its view/page objects. Its dictionary is a private field, only used in this method and declared like that:
private Dictionary<int, bool> _memberRequiresProcessingCache = new Dictionary<int, bool>();
private bool InnerMemberRequiresProcessing(IReflectionMemberInfo<TMemberInfo> member)
{
bool requires;
lock (_readLockerMrp)
{
if (!_memberRequiresProcessingCache.TryGetValue(member.MemberInfo.GetHashCode(), out requires))
{
lock (_writeLockerMrp)
{
if (!_memberRequiresProcessingCache.TryGetValue(member.MemberInfo.GetHashCode(), out requires))
{
requires = MemberRequiresProcessing(member);
_memberRequiresProcessingCache.Add(member.MemberInfo.GetHashCode(), requires);
}
}
}
}
return requires;
}
This code above is not the latest version you can find on Codeplex but I still want to know whether it might be the cause of my ObjectBuilder exceptions. While we speak I work on an update to get this old code replaced by the latest version. This is the latest implementation, unfortunately I cannot find any information why it has been changed. Might be for a bug, might be for performance...
private bool InnerMemberRequiresProcessing(IReflectionMemberInfo<TMemberInfo> member)
{
bool requires;
if (!_memberRequiresProcessingCache.TryGetValue(member.MemberInfo, out requires))
{
lock (_writeLockerMrp)
{
if (!_memberRequiresProcessingCache.TryGetValue(member.MemberInfo, out requires))
{
Dictionary<TMemberInfo, bool> tempMemberRequiresProcessingCache =
new Dictionary<TMemberInfo, bool>(_memberRequiresProcessingCache);
requires = MemberRequiresProcessing(member);
tempMemberRequiresProcessingCache.Add(member.MemberInfo, requires);
_memberRequiresProcessingCache = tempMemberRequiresProcessingCache;
}
}
}
return requires;
}
The use of the hash code looks problematic if you run a very large number of classes / members, as can happen with the singleton approach you mentioned.
The double lock was totally odd in the old one (Only one thread goes into the whole section in all cases). Note that locking as the first thing certainly hurts performance. It is a trade of, notice that instead they create a copy to avoid modifying the list as it is being read.

Async web calls bottlenecking and running sequencially

I have a web site which makes frequent requests to an external web service, and I'd like these calls to be async and parallel to avoid blocking and to speed up the site a bit. Basically, I have 8 widgets, each of which has to make its own web call(s).
For some reason, only the first 3 or so of them truly load async, and then the threads don't free up in time, and the rest of the widgets load sequencially. If i could get 3 of them to load in parallel, then 3 more in parallel, then 2 more in parallel, i'd be happy. So the issue is really that the threads aren't freeing up in time.
I'm guessing the answer has to do with some IIS configuration. I'm testing on a non-server OS, so maybe that's part of it.
Edit for #jon skeet:
I'm using reflection to invoke the web calls like this:
output = methodInfo.Invoke(webservice, parameters);
The widget actions (which eventually call the web service) are called via a jquery $.each() loop and the .load function (maybe this causes a bottleneck?). The widget actions are set up as async methods in an async controller.
Here is the code for one of the async methods (they are all set up like this):
public void MarketTradeWidgetAsync()
{
AsyncManager.OutstandingOperations.Increment();
//a bunch of market trade logic
//this eventually calls the web service
PlanUISetting uiSettingMarketQuotesConfig = WebSettingsProviderManager.Provider.GetMarketQuotes(System.Configuration.ConfigurationManager.AppSettings["Theme"], SessionValues<String>.GlobalPlanID, SessionValues<String>.ParticipantID, "MARKETQUOTES");
AsyncManager.OutstandingOperations.Decrement();
}
public ActionResult MarketTradeWidgetCompleted(MarketTradeTool markettradetool)
{
if (Session.IsNewSession)
return PartialView("../Error/AjaxSessionExpired");
else
{
ViewData["MarketData"] = markettradetool;
return PartialView(markettradetool);
}
}
And, like I said, these methods are called via jquery. My thinking is that since the action methods are async, they should give control back to the jquery after they get called, right?
SessionState = "readonly" for the page at hand fixed this issue. Evidently session locking was the issue.

Safe cache-refresh pattern for ASP.net

I've got quite a lot of code on my site that looks like this;
Item item;
if(Cache["foo"] != null)
{
item = (Item)Cache["foo"];
}
else
{
item = database.getItemFromDatabase();
Cache.insert(item, "foo", null, DateTime.Now.AddDays(1), ...
}
One such instance of this has a rather expensive getItemFromDatabase method (which is the main reason it's cached). The problem I have is that with every release or restart of the application, the cache is cleared and then an army of users come online and hit the above code, which kills our database server.
What is the typical method of dealing with these sorts of scenarios?
You could hook into the Application OnStart event in the global.asax file and call a method to load the expensive database calls in a seperate thread when the application starts.
It may also be an idea to use a specialised class for accessing these properties using a locking pattern to avoid multiple database calls when the initial value is null.

Asynchronous Callback in GWT - why final?

I am developing an application in GWT as my Bachelor's Thesis and I am fairly new to this. I have researched asynchronous callbacks on the internet. What I want to do is this: I want to handle the login of a user and display different data if they are an admin or a plain user.
My call looks like this:
serverCall.isAdmin(new AsyncCallback<Boolean>() {
public void onFailure(Throwable caught) {
//display error
}
public void onSuccess(Boolean admin) {
if (!admin){
//do something
}
else{
//do something else
}
}
});
Now, the code examples I have seen handle the data in the //do something// part directly. We discussed this with the person who is supervising me and I had the idea that I could fire an event upon success and when this event is fired load the page accordingly. Is this a good idea? Or should I stick with loading everything in the inner function? What confuses me about async callbacks is the fact that I can only use final variables inside the onSuccess function so I would rather not handle things in there - insight would be appreciated.
Thanks!
Since the inner-class/ anonymous function it is generated at runtime it needs a static memory reference to the variables it accesses. Putting final to a variable makes its memory address static, putting it to a safe memory region. The same happens if you reference a class field.
Its just standard java why you can only use Final variables inside an inner-class. Here is a great discussion discussing this topic.
When I use the AsyncCallback I do exactly what you suggested, I fire an event though GWT's EventBus. This allows several different parts of my application to respond when a user does log in.

Resources