HttpContext is null in a method called inside Parallel.For

家住魔仙堡 提交于 2019-12-22 17:39:32

问题


Posting this question after trying a lot. Doing normal for is not an option because we need to do a large amount of processing in very less time.

I have GetDataFor() inside which HttpContext.Current is used.

The code looks like this:

public void SomeMethod()
{
    var context = HttpContext.Current;

    Parallel.For(0, 100, i =>
    {
        var data = GetDataFor(i, context);
    });
}

public data GetDataFor(int i, HttpContext context)
{
    Uri requestUri = null;
    if (HttpContext.Current != null)
    {
        requestUri = HttpContext.Current.Request.Url;
        sCookie = string.Format("{0}", HttpContext.Current.Request.Headers["cookie"]);
    }
    else
    {
        requestUri = context.Request.Url;
    }

    //do something
    return data;
}

Everything works fine inside normal for loop. However, when I call it inside Parallel.For and pass HttpContext.Current, HttpContext.Current.Request, HttpContext.Current.Request.Url as method parameters:

HttpContext.Current cannot be serialized because it does not have a parameterless constructor

Passing HttpContextBase httpContext = null as parameter throws:

To be XML serializable, types which inherit from ICollection must have an implementation of Add(System.Object) at all levels of their inheritance hierarchy. System.Web.HttpApplicationStateBase does not implement Add(System.Object).

Tried making a property:

public string[] httpContextData
{
    get
    {
        string requestUrl = HttpContext.Current.Request.Url.ToString();
        string sCookie = string.Format("{0}", HttpContext.Current.Request.Headers["cookie"]);
        return new string[] { requestUrl, sCookie };
    }
}

and using in method:

var contextData = httpContextData;

which throws:

System.Uri cannot be serialized because it does not have a parameterless constructor

I did all this to send it's reference and state but unable to understand why the problem is not solving.

How do I use HttpContext.Current inside Parallel.For? What am I doing wrong here?

Btw, the needed stuff are:

HttpContext.Current.Request.Url and HttpContext.Current.Request.Headers["cookie"]


回答1:


HttpContext.Current is only available (not null) inside request-handling threads. Parallel.For creates multiple threads, none of which is has access to HttpContext.Current.

You have to pass all data that code in Parallel.For threads needs either through

  • local variables assigned before the loop or
  • TLocal instance used in Parallel.For<TLocal>.

In any event, code such as HttpContext.Current.... is out.




回答2:


The code is proprietary hence I'm only posting the relevant parts:

Since passing the following objects:

  • HttpContext.Current
  • HttpContext.Current.Request
  • HttpContext.Current.Request.Url

    as params to GetDataFor was throwing so many errors.

Also, my needs were only

  1. request url which can be re-generated by passing url as string to it's constructor
  2. and a request header's value which is essentially a string

I only passed string to GetDataFor() method:

public void SomeMethod()
{
    string requestUrl = HttpContext.Current.Request.Url.ToString();
    string sCookie = string.Format("{0}", HttpContext.Current.Request.Headers["cookie"]);

    Parallel.For(0, 100, i =>
    {
        var data = GetDataFor(i,
    requestUrl: requestUrl,
    sCookie: sCookie);
    });
}

public data GetDataFor(int i, string requestUrl = null, string sCookie = null)
{
    Uri requestUri = null;
    if (HttpContext.Current != null)
    {
        requestUri = HttpContext.Current.Request.Url;
        sCookie = string.Format("{0}", HttpContext.Current.Request.Headers["cookie"]);
    }
    else
    {
        requestUri = new Uri(requestUrl);
    }

    //do something
    return data;
}


来源:https://stackoverflow.com/questions/35483658/httpcontext-is-null-in-a-method-called-inside-parallel-for

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!