Reputation: 810
How I can implement timeout for a block of code in asp.net application without using Task
or Thread
? I don't want create new threads because HttpContext
will be NULL
in another threads.
For example, following code will not work
var task = Task.Run(() =>
{
var test = MethodWithContext();
});
if (!task.Wait(TimeSpan.FromSeconds(5)))
throw new Exception("Timeout");
object MethodWithContext()
{
return HttpContext.Current.Items["Test"]; // <--- HttpContext is NULL
}
I don't want pass current context to method, because I will have a lot of nested methods inside method... so a lot of refactor must be done for this solution
I have realized that I can assign current context to variable before creating new task and replace HttpContext
in task with this variable. This will be safe?
var ctx = HttpContext.Current;
var task = Task.Run(() =>
{
HttpContext.Current = ctx;
var test = MethodWithContext();
});
if (!task.Wait(TimeSpan.FromSeconds(5)))
throw new Exception("Timeout");
object MethodWithContext()
{
return HttpContext.Current.Items["Test"]; // now works correctly
}
Upvotes: 0
Views: 960
Reputation: 4572
You will need to pass the context of you main thread like this:
var task = Task.Run(() =>
{
// Takes the context of you current thread an passes it to the other thread.
var test = MethodWithContext(HttpContext.Current);
});
if (!task.Wait(TimeSpan.FromSeconds(5)))
throw new Exception("Timeout");
void object MethodWithContext(HttpContext ctx)
{
// Now we are operating on the context of you main thread.
return ctx.Items["Test"];
}
But the question is still:
Why do you want to create a task for this?
After starting the task you are simply waiting for its completion. You could just call your method synchronously. Although I am not sure how to limit the execution to 5 seconds if you do that.
As you have mentioned in the comments you'd like to get rid of the additional parameter because you have more than one method. This is how I'd do it:
public void YourOriginalMethod()
{
YourUtilityClass util = new YourUtilityClass(HttpContext.Current);
var task = Task.Run(() =>
{
var test = util.MethodWithContext();
});
if (!task.Wait(TimeSpan.FromSeconds(5)))
throw new Exception("Timeout");
}
public class YourUtilityClass
{
private readonly HttpContext _ctx;
public YourUtilityClass(HttpContext ctx)
{
if(ctx == null)
throw new ArgumentNullException(nameof(ctx));
_ctx = ctx;
}
public void object MethodWithContext()
{
return _ctx.Items["Test"];
}
// You can add more methods here...
}
Upvotes: 2