将HttpContext传递给Task.运行的线程

本文关键字:运行 线程 Task HttpContext | 更新日期: 2023-09-27 18:13:31

我试图通过Task.Run创建的线程传递HttpContext.Current。因为我在HttpContext.Items中有一个事务ID,这是我在线程中需要的。

public static Task<TResult> RunWithContext<TResult>(Func<TResult> function)
{
    var context = HttpContext.Current;                        
    return Task.Run(()=> { RequestHelper.SaveHttpContextInThread(context); return function(); } );
}
public static void SaveHttpContextInThread(HttpContext context)
{
    Thread.SetData(Thread.GetNamedDataSlot(RequestHelper.THREAD_SLOT_NAME), context);
}

var response = TaskHelper.RunWithContext(() => _service.UpdateJob(jobjsonstring));
var jobData = JObject.Parse(response.Result); //Compiler error here

但是编译错误

'参数1:无法从'System.Threading.Tasks.Task'转换"字符串"

出现在最后一行。

似乎是我从匿名方法返回的方式的问题。


更新

似乎是_service。UpdateJob返回任务,但我期望它返回工作对象,抱歉。

实际问题:在WebAPI中,我们想在一个新线程中运行一些任务。在HttpContext.Items中有一个值TransactionID。我们希望新创建的线程能够读取TransactionID。上面的方法是将整个HttpContext传递给新线程。

将HttpContext传递给Task.运行的线程

任务的嵌套使用可能会很混乱,特别是没有使用async/await

_ service.UpdateJob(jobjsonstring)返回一个Task。因此,执行该函数的Task.Run返回一个Task对象,结果是Task

为了得到_ service.UpdateJob调用的结果,你必须使用response.Result.Result

 var jobData = JObject.Parse(response.Result.Result);

另一种选择(不需要async/await)是在函数内部返回Result,例如

var response = TaskHelper.RunWithContext(() => _service.UpdateJob(jobjsonstring).Result);