如何在不使用Task
或Thread
的情况下为asp.net应用程序中的代码块实现超时?我不想创建新线程,因为HttpContext
在另一个线程中将是NULL
。
例如,以下代码无效
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
}
我不希望将当前上下文传递给方法,因为我在方法中会有很多嵌套方法...所以必须为这个解决方案做很多重构
我已经意识到我可以在创建新任务之前将当前上下文分配给变量,并使用此变量替换任务中的HttpContext
。这样会安全吗?
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
}
答案 0 :(得分:2)
您将需要像这样传递主线程的上下文:
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"];
}
但问题仍然是:
为什么要为此创建任务?
启动任务后,您只需等待其完成。你可以同步调用你的方法。虽然我不知道如果你这样做,如何将执行限制为5秒。
正如您在评论中提到的那样,您希望摆脱额外的参数,因为您有多个方法。我就是这样做的:
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...
}