在Parallel.Foreach循环上设置超时

时间:2013-09-21 18:02:41

标签: c# .net timeout parallel.foreach

我必须从我的WCF服务向客户端发送List我的自定义对象(“拨号”)。此对象有5个属性:Id,Name,Type,Individual_avg ,Dept_avg。 Id,Name和Type的值来自一个表,但Individual_avg和dept_avg来自第三方服务。要求是:

  1. 从表中加载静态属性 - Id,Name,Type
  2. 在WCF服务中调用一个方法,该方法从第三方服务获取其他2个属性值。
  3. 我必须在30秒后超时调用第三方服务。也就是说,如果服务响应超过30秒,我必须发送只有从表中提取的3个属性的对象(Id,Name ,键入)并将其他2个属性设置为null。例如,Dials中有5个List。产生5个线程来调用第三方服务以获得2个属性。如果在获取2 Dials的值后发生超时,请发送List并为这2个Dials设置所有属性并且仅为其他3个拨号设置了ID,名称和类型。我有以下代码来实现它。

    public DialResponse GetDials(DialRequest req)
    {
        DialResponse response = new DialResponse();
        var indiDials = new List<DialDetails>();
        foreach (var c in indiDialIdToShow)
        {
            var indiObj = _repository.FindQueryable<DashboardDial_Tbl>().Where(p => p.DialId == c.DialIdToShow && p.IsActive == true).Select(p => new DialDetails()
                {
                    Id = p.DialId,
                    Name = p.DialName,
                    Type = p.DialType,
                 }).SingleOrDefault();
            indiDials.Add(indiObj);
        }
    var timeout = 30000; // 30 seconds
    var cts = new CancellationTokenSource();
    var token = new CancellationToken();
    token = cts.Token;
    var myOptions = new ParallelOptions { CancellationToken = cts.Token };
    using (var t = new Timer(_ => cts.Cancel(), null, timeout, -1))
    {
        Parallel.ForEach(indiDials, myOptions, c =>
        {
            DialDetails newDial = c;
            ReadConfig(c.Id, userName, ref newDial);
            //send a reference to the "dial" object and set the 2 properties on the object
    
         });
     }
    response.DialsList = indiDials;
    }
    
    private void ReadConfig(string userName,ref DialDetails dialObj)
    {
       //call the 3rd party service
       dialObj.Individual_avg = serviceResponse.someValue;
       dialObj.dept_avg = serviceResponse.anotherValue;
    }
    

    为了测试“超时”功能,我在Thread.Sleep(40000)方法中放了一个"ReadConfig"。这会返回一个空的“拨号”列表,而不是发送只有3个属性的“拨号”(Id,名称,类型)设置。我应该做出哪些更改,以使这段代码按预期工作?

1 个答案:

答案 0 :(得分:1)

ReadConfig正在本地执行修改,因此indiDials不会更新。您可以将其转换为函数以返回已修改的项目。示例代码:

private DialDetails ReadConfig(string userName,ref DialDetails dialObj)
{
   //call the 3rd party service
   dialObj.Individual_avg = serviceResponse.someValue;
   dialObj.dept_avg = serviceResponse.anotherValue;

   retun dialObj;
}

从循环中调用它以便修改List

indiDials[indiDials.IndexOf(newDial)] = ReadConfig(userName, ref newDial);