简体   繁体   English

使用TaskFactory.StartNew内部循环:状态对象不起作用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM