Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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#_.net_C# 4.0_Data Structures - Fatal编程技术网

C# 如何在所有线程完成执行后显示消息框?

C# 如何在所有线程完成执行后显示消息框?,c#,.net,c#-4.0,data-structures,C#,.net,C# 4.0,Data Structures,希望使用线程分解一个非常繁重的函数,并在工作完成时显示一个消息框 以下是类似代码: for (int index = 0; index < tests.Count; index/=3) { System.Threading.Thread t = new System.Threading.Thread( () => SomeFunction(tests.GetRange(start, 3))); t.Start(); } for

希望使用线程分解一个非常繁重的函数,并在工作完成时显示一个消息框

以下是类似代码:

for (int index = 0; index < tests.Count; index/=3)
{
    System.Threading.Thread t =
        new System.Threading.Thread(
            () => SomeFunction(tests.GetRange(start, 3)));
    t.Start();
}
for(int index=0;indexSomeFunction(tests.GetRange(start,3));
t、 Start();
}
希望在所有这些线程完成执行并完成整个工作后显示一个消息框。我该怎么做?
Join将无法工作,因为它将导致与不使用线程相同的时间。

如果使用任务而不是线程,则更容易:

var tasks = new List<Task>();
for (int index = 0; index < tests.Count; index/=3)
{
    var task = Task.Factory.StartNew(() => SomeFunction(tests.GetRange(start, 3)));
    tasks.Add(tasks);
}

Task.WaitAll(tasks.ToArray());
MessageBox.Show("Done!");
var tasks=newlist();
对于(int index=0;indexSomeFunction(tests.GetRange(start,3));
任务。添加(任务);
}
Task.WaitAll(tasks.ToArray());
MessageBox.Show(“完成!”);
如果确实要使用线程,可以选择使用等待句柄:

var waitHandles = new List<EventWaitHandle>();
for (int index = 0; index < tests.Count; index/=3)
{
    var waitHandle = new ManualResetEvent(false);
    waitHandles.Add(waitHandle);
    System.Threading.Thread t =
        new System.Threading.Thread(
            () =>
            {
                SomeFunction(tests.GetRange(start, 3));
                waitHandle.Set();
            });
    t.Start();
}
WaitHandle.WaitAll(waitHandles.ToArray());
MessageBox.Show("Done!");
var waitHandles=new List();
对于(int index=0;index
{
SomeFunction(tests.GetRange(start,3));
waitHandle.Set();
});
t、 Start();
}
WaitHandle.WaitAll(waitHandles.ToArray());
MessageBox.Show(“完成!”);
请注意,如果在UI线程上调用此函数,UI将被冻结,直到所有线程完成。如果您想避免这种情况,更好的选择是使用
Task.Factory.continuewheall
,正如斯里拉姆·萨基维尔的回答中所建议的那样


顺便问一下,你确定
索引/=3
部分吗?如果
test.Count>0

使用任务而不是线程,则会导致循环永远运行:

var tasks = new List<Task>();
for (int index = 0; index < tests.Count; index/=3)
{
    var task = Task.Factory.StartNew(() => SomeFunction(tests.GetRange(start, 3)));
    tasks.Add(tasks);
}

Task.WaitAll(tasks.ToArray());
MessageBox.Show("Done!");
var tasks=newlist();
对于(int index=0;indexSomeFunction(tests.GetRange(start,3));
任务。添加(任务);
}
Task.WaitAll(tasks.ToArray());
MessageBox.Show(“完成!”);
如果确实要使用线程,可以选择使用等待句柄:

var waitHandles = new List<EventWaitHandle>();
for (int index = 0; index < tests.Count; index/=3)
{
    var waitHandle = new ManualResetEvent(false);
    waitHandles.Add(waitHandle);
    System.Threading.Thread t =
        new System.Threading.Thread(
            () =>
            {
                SomeFunction(tests.GetRange(start, 3));
                waitHandle.Set();
            });
    t.Start();
}
WaitHandle.WaitAll(waitHandles.ToArray());
MessageBox.Show("Done!");
var waitHandles=new List();
对于(int index=0;index
{
SomeFunction(tests.GetRange(start,3));
waitHandle.Set();
});
t、 Start();
}
WaitHandle.WaitAll(waitHandles.ToArray());
MessageBox.Show(“完成!”);
请注意,如果在UI线程上调用此函数,UI将被冻结,直到所有线程完成。如果您想避免这种情况,更好的选择是使用
Task.Factory.continuewheall
,正如斯里拉姆·萨基维尔的回答中所建议的那样


顺便问一下,你确定
索引/=3
部分吗?如果
test.Count>0
..

使用.Net4.0+,它将导致循环永远运行。使用任务并行库

var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
var tasks = ...;//Start tasks
Task.Factory.ContinueWhenAll(tasks, antecedents =>
{
   //Show messagebox here 
},CancellationToken.None,TaskContinuationOptions.None,uiContext);

使用
continuewheall
异步等待,并使用
FromCurrentSynchronizationContext
在UIThread中执行回调。如果使用.Net4.0+,请扔掉旧的线程。使用任务并行库

var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
var tasks = ...;//Start tasks
Task.Factory.ContinueWhenAll(tasks, antecedents =>
{
   //Show messagebox here 
},CancellationToken.None,TaskContinuationOptions.None,uiContext);

使用
continuewheall
异步等待,并使用CurrentSynchronizationContext中的
执行UIThread中的回调。为什么不改用
Parallel.Foreach()
,它将自动等待所有。大概是这样的:

Parallel.ForEach(Enumerable.Range(1, 10), i => 
{
    Console.WriteLine("{0} - {1}", i, GetTotal());
});

为什么不改为使用
Parallel.Foreach()
,它将自动等待所有。大概是这样的:

Parallel.ForEach(Enumerable.Range(1, 10), i => 
{
    Console.WriteLine("{0} - {1}", i, GetTotal());
});


你知道并行的
吗?对于这里的
描述,你知道你的循环最多只执行一次,对吧?@CareyGregory,不,它将永远执行,除非
tests.Count==0
@thomaslevoops,我的错。你是对的。你知道并行吗。对于这里的描述,你确实意识到你的循环将始终执行一次,最多一次,对吗?@CareyGregory,不,它将永远执行,除非
tests.Count==0
@thomaslevsque Oops,我的错。没错。是的,只是它只支持循环变量的线性递增(即
i++
)。。。OP使用
index/=3
(这在我看来没有多大意义)。是的,除了它只支持循环变量的线性递增(即
i++
)。。。OP使用
index/=3
(这在我看来没有多大意义)。如果从UI线程调用它,则
WaitAll
是不正确的choice@SriramSakthivel,说得好。我更新了我的答案,提到了这一点,并参考了你的答案。如果这是从UI调用,线程
WaitAll
是不对的choice@SriramSakthivel,说得好。我更新了我的答案以提及这一点,并参考了您的答案。在for循环中:var task=System.Threading.Tasks.task.Factory.StartNew(()=>SomeFunction(cnt,tests.GetRange(start,3));任务。添加(任务);然后:System.Threading.Tasks.Task.Factory.continuewhell(Tasks.ToArray(),antecedents=>{//Show messagebox here if(timer!=null)timer.Stop();messagebox.Show(timer.elapsedmillesons.ToString();});但是,不知何故,Somefunction()没有执行调试并查看是否执行了循环,如果是,则在
Somefunction
中添加一个消息框,并查看是否在for循环中执行:var task=System.Threading.Tasks.task.Factory.StartNew(()=>Somefunction(cnt,tests.GetRange(start,3));任务。添加(任务);然后:System.Threading.Tasks.Task.Factory.continuewhell所有(Tasks.ToArray(),antecedents=>{//Show messageb