在 Parallel.Foreach 循环上设置超时

本文关键字:设置 超时 循环 Parallel Foreach | 更新日期: 2023-09-27 18:32:11

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

  1. 从表中加载静态属性 - Id,名称,类型
  2. 调用 WCF 服务中从第三方服务获取其他 2 个属性值的方法。

我必须在 30 秒后使对第三方服务的调用超时。也就是说,如果服务响应时间超过 30 秒,我必须发送仅包含从表中获取的 3 个属性(Id、Name、Type)的对象,并将其他 2 个属性设置为 null。例如,List中有 5 个Dials。生成 5 个线程以调用第三方服务以获取 2 个属性。如果在获取 2 个Dials的值后发生超时,请发送为这 2 个Dials设置所有属性的List,并且仅为其他 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;
}

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

在 Parallel.Foreach 循环上设置超时

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);