问题
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 inParallel.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
- request url which can be re-generated by passing url as
string
to it's constructor - 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