在Parallel.Foreach回路设置超时回路、Parallel、Foreach

2023-09-07 08:52:09 作者:滚出我的心

我要送一个列表我的自定义对象(拨号)到客户端从我的WCF service.This对象有5属性:ID,名称,类型,Individual_avg,Dept_avg。对于ID,名称和类型的值从表中到来,但Individual_avg和dept_avg是从第三方的服务。未来的要求是:

I have to send a List of my custom object("Dial") to the client from my WCF service.This object has 5 properties:Id,Name,Type,Individual_avg,Dept_avg. The values for Id,Name and Type are coming from a table but the Individual_avg and dept_avg are coming from a 3rd party service.The requirement is:

加载静态属性 - 从表编号,名称,类型 呼叫来自第三方服务获取对方2属性值的WCF服务中的方法。

我在30 seconds.That超时调用第三方服务,如果服务时间超过30秒的反应,我必须与只有3个属性获取从表(ID,姓名发送对象,类型)和设置其他2个属性为null。例如,有5个拨号列表研究。产卵5个线程调用第三方服务来获得2 properties.If获取值2 拨号后发生超时,发送列表与这2 拨号,只有编号,名称和类型设置为其他3拨号设置的所有属性。我有以下的code来实现它。

I have to timeout the call to 3rd party service after 30 seconds.That is,if the service takes more than 30 seconds to respond,I have to send the objects with only the 3 properties fetched from the table(Id,Name,Type) and set the other 2 properties to null. For example,there are 5 Dials in the List. Spawn 5 threads to call the 3rd party service to get the 2 properties.If the timeout occurs after getting the values for 2 Dials,send the List with all properties set for these 2 Dials and only Id,Name and Type set for the other 3 Dials. I have the following code to achieve it.

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 method.This返回拨号,而不是发送拨号的只有3个属性(ID,名称,类型)设置一个空列表。我应该什么样的变化,使这片code ++工程的按计划?

To test the "timeout" functionality,I put a Thread.Sleep(40000) in "ReadConfig" method.This returns an empty list of "Dials" instead of the sending "Dials" with only 3 properties(Id,Name,Type) set. What changes should I make so that this piece of code works as intended?

推荐答案

ReadConfig 在本地,因此进行修改 indiDials 未更新。你可以将它转换成一个函数返回修改后的项目。样品code:

ReadConfig is performing the modifications locally and thus indiDials is not updated. You can convert it into a function to return the modified item. Sample code:

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

和从循环调用它使得列表修改

And call it from the loop such that the List is modified:

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