方法超时而不创建新线程

时间:2017-06-01 09:04:37

标签: c# asp.net .net

如何在不使用TaskThread的情况下为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
}

编辑:

我不希望将当前上下文传递给方法,因为我在方法中会有很多嵌套方法...所以必须为这个解决方案做很多重构

EDIT2:

我已经意识到我可以在创建新任务之前将当前上下文分配给变量,并使用此变量替换任务中的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
    }

1 个答案:

答案 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...
}