Our application has a lot of calls to Task.Factory.StartNew(Action action). Unfortunately, when doing this, the culture is not set, and furthermore, there is no error handling. I began with a starter class that would do both:
public static class TaskBuilder
{
private static Action<System.Exception> _exceptionCallback;
public static Task StartNew(Action action, CultureInfo cultureInfo, Action<System.Exception> exceptionCallback)
{
_exceptionCallback = exceptionCallback;
return Task.Factory.StartNew(() =>
{
Thread.CurrentThread.CurrentUICulture = cultureInfo;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);
action.Invoke();
}).ContinueWith(t => ManageException(t.Exception), TaskContinuationOptions.OnlyOnFaulted);
}
private static void ManageException(System.Exception e)
{
if (_exceptionCallback != null)
{
_exceptionCallback(e);
}
}
}
But then I realized that a better approach would be an interceptor. I would like to intercept the call to StartNew so that the new thread contains the culture and error handling code. My attempt at this produced the following code:
public class TaskInterceptionHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Thread.CurrentThread.CurrentUICulture = // How do I get parent cultureInfo?;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);
var methodReturn = getNext().Invoke(input, getNext);
if (methodReturn.Exception != null)
{
// How do I throw the exception to the calling thread here?
}
return methodReturn;
}
public int Order { get; set; }
}
Here is where I'm stumped. Firstly, how do I get the parent CultureInfo? Secondly How do I return the exception to the calling thread? and How do I use this class in my calls? I.e. how do I replace the existing Task.Factory.StartNew(..)
I'm using Unity, and I'm in unfamiliar territory here. Any help or guidance would be appreciated, or is there even a better solution? Maybe I'm starting on the wrong foot?
I'm using .NET 4.5
Most of the feedback I'm getting below seems to avoid the interceptor route. Is it safe to assume using an interceptor is the wrong way to go? If someone can guide me in that direction, it would allow me to do a comparison. If the answer to the question is yes, I'd like to know how?
CultureInfo.DefaultThreadCurrentCulture
property (and its UICulture equivvalent) that lets you set the culture for all threads in the app domain. – InStartNew
inspecting the returnedTask
, not passing in a callback to execute when there is an exception. You're turning of the TPL's error handling, which is one of it's most useful features. – ChristeanTaskScheduler
– Cornett_errorCallback
field is shared by all tasks created like this, that's what I meant by "not thread-safe" – In