Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在任务并行库中处理多个任务返回值_C#_Task Parallel Library_Task_Return Value - Fatal编程技术网

C# 在任务并行库中处理多个任务返回值

C# 在任务并行库中处理多个任务返回值,c#,task-parallel-library,task,return-value,C#,Task Parallel Library,Task,Return Value,我在处理任务并行库中写入的多个任务返回值时遇到问题 我的代码如下所示: . 使用来自第三方的数据创建一组关键点和对象 . 它为字典中的每个键启动任务 . 在每个任务中,将再次使用与该键关联的用户对象启动一组任务(从上面的步骤2开始) . 一旦执行了所有内部任务,我想根据返回值更新用户对象 到目前为止,我已经提出了以下代码: void ProcessKeys(ExchangeKey eKey) { // Create List of T

我在处理任务并行库中写入的多个任务返回值时遇到问题

我的代码如下所示: . 使用来自第三方的数据创建一组关键点和对象 . 它为字典中的每个键启动任务 . 在每个任务中,将再次使用与该键关联的用户对象启动一组任务(从上面的步骤2开始) . 一旦执行了所有内部任务,我想根据返回值更新用户对象

到目前为止,我已经提出了以下代码:

        void ProcessKeys(ExchangeKey eKey)
        {   
            // Create List of Tasks
            var retValues = new List<Task<ReturnStatus>>();
            // The ContainsKey here is commented out but I have a comparer method which can compare the compound keys
            if (TaskProcessor.lstInputsFromUser.Count > 0 )//  && TaskProcessor.lstInputsFromUser.ContainsKey(eKey))
            {
                // Everytime dData will be filled with data from outside world
                OrderBook myOrder = new OrderBook();
                // Remove the key as the next object will be inserted somewhere else when new data arrives
                dData.TryGetValue(eKey, out myOrder);
                if (myOrder != null)
                {
                    foreach (var indiElement in TaskProcessor.lstInputsFromUser[eKey])
                    {
                        // If the data is already run for the expected number of cycles to total cyles, don't run again
                        if (indiElement.NoOfCycles != indiElement.TotalNoOfCycles)
                        {
                            var singleRetVal = new Task<ReturnStatus>( () => ProcessData(myOrder, indiElement));
                            singleRetVal.Start();
                            retValues.Add(singleRetVal);
                        }
                    }
                }
                // Wait till all tasks are completed
                // Here also I am facing problem of how to wait on the 1-exchangekey and 5-tasks policy
                Task.WaitAll(retValues.ToArray());

                var results = retValues.Select(t => t.Result)
                     .ToList();

                if (results != null)
                {
                    Console.WriteLine("Shall print two times only");
                    foreach (var retResult in results)
                    {
                        if (TaskProcessor.ReturnStatusAfterCalc.Keys.Contains(retResult.ID))
                        {
                            TaskProcessor.ReturnStatusAfterCalc[retResult.ID] = retResult;
                            var myObj = TaskProcessor.lstInputsFromUser[eKey].FirstOrDefault(indi => indi.ID == retResult.ID);
                            if (myObj != null)
                            {
                                // Here I am unable to update my original object
                                myObj.NoOfCycles += retResult.CyclesCompleted;
                                /// arEvent.Set();
                                // Task.Run( () => Update database with myObj.NoOfCyles value for the listInputsFromUser[eKey]
                            }
                        }
                        else
                        {
                            // TaskProcessor.ReturnStatusAfterCalc[retResult.ID] = new ReturnStatus();
                            TaskProcessor.ReturnStatusAfterCalc.TryAdd(retResult.ID, retResult);
                            var myObj = TaskProcessor.lstInputsFromUser[eKey].FirstOrDefault(indi => indi.ID == retResult.ID);
                            if (myObj != null)
                            {
                                // Here I am unable to update my original object
                                myObj.NoOfCycles += retResult.CyclesCompleted;
                                // Task.Run( () => Update database with myObj.NoOfCyles value for the listInputsFromUser[eKey]
                                // arEvent.Set();
                            }
                        }
                    }
                }
            }
        }
void进程键(交换键)
{   
//创建任务列表
var retValues=新列表();
//这里的ContainsKey被注释掉了,但是我有一个comparer方法可以比较复合键
if(TaskProcessor.lstInputsFromUser.Count>0)/&&TaskProcessor.lstInputsFromUser.ContainsKey(eKey))
{
//每次dData都将充满来自外部世界的数据
OrderBook myOrder=新的OrderBook();
//删除密钥,因为新数据到达时,下一个对象将插入其他位置
dData.TryGetValue(eKey,out myOrder);
if(myOrder!=null)
{
foreach(TaskProcessor.lstInputsFromUser[eKey]中的变量indirement)
{
//如果数据已按总循环数的预期循环数运行,则不要再次运行
if(indirement.NoOfCycles!=indirement.TotalNoOfCycles)
{
var singleRetVal=新任务(()=>ProcessData(myOrder,indirement));
singleRetVal.Start();
添加(singleRetVal);
}
}
}
//等待所有任务完成
//在这里,我还面临着如何等待1-exchangekey和5-tasks策略的问题
Task.WaitAll(retValues.ToArray());
var results=retValues.Select(t=>t.Result)
.ToList();
如果(结果!=null)
{
Console.WriteLine(“只能打印两次”);
foreach(var retResult in results)
{
if(TaskProcessor.ReturnStatusAfterCalc.Keys.Contains(retResult.ID))
{
TaskProcessor.ReturnStatusAfterCalc[retResult.ID]=retResult;
var myObj=TaskProcessor.lstInputsFromUser[eKey].FirstOrDefault(indi=>indi.ID==retResult.ID);
if(myObj!=null)
{
//这里我无法更新我的原始对象
myObj.NoOfCycles+=retResult.CyclesCompleted;
///arEvent.Set();
//Task.Run(()=>使用listInputsFromUser[eKey]的myObj.NoOfCyles值更新数据库
}
}
其他的
{
//TaskProcessor.ReturnStatusAfterCalc[retResult.ID]=新的ReturnStatus();
TaskProcessor.ReturnStatusAfterCalc.TryAdd(retResult.ID,retResult);
var myObj=TaskProcessor.lstInputsFromUser[eKey].FirstOrDefault(indi=>indi.ID==retResult.ID);
if(myObj!=null)
{
//这里我无法更新我的原始对象
myObj.NoOfCycles+=retResult.CyclesCompleted;
//Task.Run(()=>使用listInputsFromUser[eKey]的myObj.NoOfCyles值更新数据库
//arEvent.Set();
}
}
}
}
}
}
主要的问题是,代码运行的内部任务集比所需任务集运行的次数要多。此外,我还面临使用返回值更新实际对象的问题,因为它多次执行内部任务

请求任何人在这方面帮助我。虽然(true)不好,但我将用计时器中包含的设置事件替换它

在几句评论之后,我觉得我的例子和解释实际上并没有给出问题的描述。很抱歉给你们带来麻烦

问题描述: 假设我从一家交易所订购了10个符号。用户1订购了3个符号,用户2订购了7个符号。现在,交易所将继续发送这10个符号的数据,用户1和用户2将给我一定的价格,以便订购这10个符号。我将运行10个任务来检查传入的10个符号的价格。稍后,用户1将返回o添加剩余的7个符号价格输入。因此,我必须运行13个不同的任务,其中包含13个用户对象和10个符号数据,因为每个用户对象可能包含不同的价格和条件

编辑:


在Panagiotis Kanavos的帮助下,我意识到Parallel.ForEach可以用来存储返回结果,而不需要执行任务。此处提供的主要逻辑和其他不必要的代码将根据注释删除。

@SNR
async/await
没有中断。尽管您的代码做了很多奇怪的事情。例如,使用
线程。Sleep(1)
,同时使用
任务。运行
TaskFactory。使用任务列表启动新的
,然后
ProcessKeys
使用冷任务?即使它已经在自己的任务中运行了?您想做什么?为什么不简单地调用
Parallel.ForEach(dbData…)
?不要试图reinvent@SNR你想做什么?你想解决的实际问题是什么