Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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# 并行计算。NET 4.0_C#_.net_Task - Fatal编程技术网

C# 并行计算。NET 4.0

C# 并行计算。NET 4.0,c#,.net,task,C#,.net,Task,我正在做并行编程的第一步。我将CalculateSlots重写为CalculateSlotsAsync。它可以很好地工作(快3倍) 我的问题是:它写得正确吗? 我是否需要使用最新的async awayt模式?如果需要,如何使用 private void CalculateSlots(bool isCalculateAllSlots) { foreach (IndicatorSlot indicatorSlot in strategy.Slot) { if (isC

我正在做并行编程的第一步。我将CalculateSlots重写为CalculateSlotsAsync。它可以很好地工作(快3倍)

我的问题是:它写得正确吗? 我是否需要使用最新的async awayt模式?如果需要,如何使用

private void CalculateSlots(bool isCalculateAllSlots)
{
    foreach (IndicatorSlot indicatorSlot in strategy.Slot)
    {
        if (isCalculateAllSlots || !indicatorSlot.IsCalculated)
            CalculateStrategySlot(indicatorSlot.SlotNumber);
    }
}

private void CalculateSlotsAsync(bool isCalculateAllSlots)
{
    var tasks = new List<Task>();
    foreach (IIndicatorSlot indicatorSlot in strategy.Slot)
    {
        if (isCalculateAllSlots || !indicatorSlot.IsCalculated)
        {
            IIndicatorSlot slot = indicatorSlot;
            Task task = Task.Factory.StartNew(() => CalculateStrategySlot(slot.SlotNumber));
            tasks.Add(task);
        }
    }
    Task.WaitAll(tasks.ToArray());
}
private void calculateslot(bool isCalculateAllSlots)
{
foreach(IndicatorSlot IndicatorSlot in strategy.Slot)
{
if(isCalculateAllSlots | | |!指示符批次.IsCalculated)
计算类别批次(指示符批次、插槽编号);
}
}
私有void计算lotsasync(bool isCalculateAllSlots)
{
var tasks=新列表();
foreach(IIndicatorSlot indicatorSlot in strategy.Slot)
{
if(isCalculateAllSlots | | |!指示符批次.IsCalculated)
{
IIIndicatorSlot插槽=指示器插槽;
Task Task=Task.Factory.StartNew(()=>CalculateStrategySlot(slot.SlotNumber));
任务。添加(任务);
}
}
Task.WaitAll(tasks.ToArray());
}
测试i7-3630QM@2.40Gh

// Executed for 96 sec. 
for (int i = 0; i < 1000; i++)
    CalculateSlots(true);

// Executed for 34 sec. 
for (int i = 0; i < 1000; i++)
    CalculateSlotsAsync(true);
//执行96秒。
对于(int i=0;i<1000;i++)
计算批次(正确);
//执行34秒。
对于(int i=0;i<1000;i++)
CalculateSlotsAsync(真);

对于数据并行操作,通常可以使用PLINQ简化实现:

strategy.Slot.AsParallel()
             .Where(slot => isCalculateAllSlots || !indicatorSlot.IsCalculated)
             .ForAll(slot => CalculateStrategySlot(slot.SlotNumber));
但是,在您的情况下,每个项目都需要相对较长的计算时间,因此我建议将它们作为任务保留,但将它们标记为(这通常会在专用线程上执行它们,而不是在线程池中)

Reply
Task.WaitAll
导致调用线程(在您的例子中是UI线程)阻塞,直到所有指定的任务完成。(PLINQ
ForAll
的行为类似)

为了让UI保持响应性,您需要从阻塞方法切换到异步方法。例如,假设您有:

Task.WaitAll(tasks.ToArray());
UpdateUI(strategy.Slot);    // must be called on UI thread
您可以将其替换为:

Task.Factory.ContinueWhenAll(tasks.ToArray(), completedTasks =>
{
    // callback on UI thread
    UpdateUI(strategy.Slot);
},
    CancellationToken.None,
    TaskContinuationOptions.None,
    TaskScheduler.FromCurrentSynchronizationContext());

在实践中,您还需要学习如何使用
CancellationToken
允许用户在操作完成之前放弃操作。

对于数据并行操作,您通常可以使用PLINQ简化实现:

strategy.Slot.AsParallel()
             .Where(slot => isCalculateAllSlots || !indicatorSlot.IsCalculated)
             .ForAll(slot => CalculateStrategySlot(slot.SlotNumber));
但是,在您的情况下,每个项目都需要相对较长的计算时间,因此我建议将它们作为任务保留,但将它们标记为(这通常会在专用线程上执行它们,而不是在线程池中)

Reply
Task.WaitAll
导致调用线程(在您的例子中是UI线程)阻塞,直到所有指定的任务完成。(PLINQ
ForAll
的行为类似)

为了让UI保持响应性,您需要从阻塞方法切换到异步方法。例如,假设您有:

Task.WaitAll(tasks.ToArray());
UpdateUI(strategy.Slot);    // must be called on UI thread
您可以将其替换为:

Task.Factory.ContinueWhenAll(tasks.ToArray(), completedTasks =>
{
    // callback on UI thread
    UpdateUI(strategy.Slot);
},
    CancellationToken.None,
    TaskContinuationOptions.None,
    TaskScheduler.FromCurrentSynchronizationContext());

在实践中,您还需要学习如何使用
CancellationToken
允许用户在操作完成之前放弃操作。

代码复查不是这样做的目的。代码看起来还可以,但可以使用(P)Linq和/或Parallel.ForEach()进行简化。我已经使用了两年,但仍然无法理解它的确切用途。我真的很害怕在这里问一些问题,特别是回答问题。米罗斯拉夫波夫:我想亨克的意思是,这个网站可能更适合这些问题。但不要害怕问问题;可能发生的最坏情况是,它将在没有收到任何答案的情况下关闭。代码审查不是这样做的目的。代码看起来还可以,但可以使用(P)Linq和/或Parallel.ForEach()进行简化。我已经使用了两年,但仍然无法理解它的确切用途。我真的很害怕在这里问一些问题,特别是回答问题。米罗斯拉夫波夫:我想亨克的意思是,这个网站可能更适合这些问题。但不要害怕问问题;最糟糕的情况是,它将在没有收到任何答复的情况下关闭。谢谢@Douglas!已测试Asparle()代码。比我的干净多了。我错过了一些东西。如果它是并行的,为什么在进行完整计算时会阻塞我的UI?+1谢谢@Douglas。遗憾的是,我不能以+5投票赞成这种建设性的回答。用户必须能够正确地评价一行提示和一个带有多个示例的答案。不客气:-)对我来说重要的是,您的问题得到了正确的解决。谢谢@Douglas!已测试Asparle()代码。比我的干净多了。我错过了一些东西。如果它是并行的,为什么在进行完整计算时会阻塞我的UI?+1谢谢@Douglas。遗憾的是,我不能以+5投票赞成这种建设性的回答。用户必须能够正确地评价一行提示和带有多个示例的答案。不客气:-)对我来说重要的是,您的查询得到了正确的解决。