[英]Using TaskFactory.StartNew inside loop: state object doesn't work
First of all I initialize searchContext list: 首先,我初始化searchContext列表:
var searchContexts = new List<SearchContext>();
for (byte pageNumber = 1; pageNumber < 6; pageNumber++)
{
var searchContext = GetSearchContext(context, vendor, workRequest, pageNumber);
searchContexts.Add(searchContext);
}
where SearchContext is defined as follows: 其中SearchContext的定义如下:
public class SamoSearchContext
{
public WorkRequest WorkRequest
{ get; set; }
public Vendor Vendor
{ get; set; }
public WorkResponse WorkResponse
{ get; set; }
public byte PageNumber
{ get; set; }
}
Then for each searchContext start new thread: 然后为每个searchContext启动新线程:
var tasks = new Task[taskCount];
var taskScheduler = TaskScheduler.Default;
var index = 0;
foreach (var searchContext in searchContexts)
{
var ssc = searchContext;
tasks[index] = Task.Factory.StartNew((obj) => SendSearchRequest(ssc, token),
ssc, token, TaskCreationOptions.AttachedToParent, taskScheduler);
index++;
}
SendSearchRequest() method call outside service to get the next search result page (by pageNumber). 服务外部的SendSearchRequest()方法调用以获取下一个搜索结果页面(按pageNumber)。 Here is the implementation: 这是实现:
private void SendSearchRequest(SamoSearchContext context, CancellationToken token)
{
if (token.IsCancellationRequested)
return;
var workRequest = context.WorkRequest;
workRequest.@params.PRICE_PAGE = context.PageNumber;
context.WorkResponse = ServiceClient.GetWorkResponse<WorkRequest, WorkResponse>(ServiceOperations.GetPrice, workRequest, context.Vendor.UniformCode, context.Vendor.ID);
} }
But reading logs after the loop execution I see that pageNumber is always = 4. 但是在循环执行后读取日志,我看到pageNumber总是= 4。
Could not understand what's wrong? 不明白怎么了?
The matter is when I create SearchContext list, I indiscreetly used copy workRequest by reference (newSearchContext.WorkRequest = workRequest). 问题是当我创建SearchContext列表时,我不经意地使用了通过引用复制workRequest的方式(newSearchContext.WorkRequest = workRequest)。 So all SearchContexts in the list reference to the one workRequest instance. 因此,列表中的所有SearchContext都引用一个workRequest实例。 Then, in SendRequest() each time I've changed PRICE_PAGE field of this one instance. 然后,每次我更改此实例的PRICE_PAGE字段时,在SendRequest()中。 So it was the same, a bit strange that it always = 4, but not a random number from 1 to 5. 所以总是一样,总是= 4,而不是1到5之间的随机数,这有点奇怪。
But, nevertheless, now I implement Clone() extension method for WorkRequest which copy the object field by field into a new instance. 但是,尽管如此,现在我为WorkRequest实现了Clone()扩展方法,该方法将对象字段逐字段复制到新实例中。 Now it works. 现在可以了。 Thanks everybody for participation! 谢谢大家的参与!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.