C# Task.ContinueWith BeginInvoke未按预期工作

C# Task.ContinueWith BeginInvoke未按预期工作,c#,task,C#,Task,考虑以下代码: Task task1; Task task2; private void button1_Click(object sender, EventArgs e) { task1 = Task.Run(() => { for (int i = 0; i < 100000; i++) { BeginInvoke(new Action<int>((int n) =>

考虑以下代码:

Task task1;
Task task2;
private void button1_Click(object sender, EventArgs e)
{
    task1 = Task.Run(() =>
    {
        for (int i = 0; i < 100000; i++)
        {
            BeginInvoke(new Action<int>((int n) =>
            {
                listView1.Items.Add(n.ToString());
            }), i);
        }
    });            
    task2 = task1.ContinueWith(t =>
    {
        MessageBox.Show("Why isn't this reached");
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

private void button2_Click(object sender, EventArgs e)
{
    MessageBox.Show(String.Format("task1 status:{0}\r\ntask2 status:{1}", task1.Status, task2.Status));
}
task1;
任务2;
私有无效按钮1\u单击(对象发送者,事件参数e)
{
task1=Task.Run(()=>
{
对于(int i=0;i<100000;i++)
{
BeginInvoke(新操作((int n)=>
{
listView1.Items.Add(n.ToString());
}),i);
}
});            
task2=task1.ContinueWith(t=>
{
Show(“为什么没有达到这个目标”);
},TaskScheduler.FromCurrentSynchronizationContext());
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
Show(String.Format(“task1状态:{0}\r\n task2状态:{1}”、task1.status、task2.status));
}
如果我在Windows 8、.NET Framework 4.5.2上运行此功能,当我单击按钮2时,会得到以下输出:

任务1状态:RANTO完成

任务2状态:WaitingToRun

即使我使用ContinueWith,这怎么可能呢


我知道BeginInvoke只是让委托排队执行,如果我使用Invoke,它就可以正常工作。这是一个bug还是干扰了BeginInvoke?有什么想法吗?提前感谢。

我没有主要来源,但声明消息队列的记录限制为10000条(Hans Passant是该网站上windows窗体的专家之一,因此我相信他的话,这个限制是存在的)


因为您要将100000条记录放在那里,它要么将您的ContinueWith从堆栈中推出,要么从一开始就没有添加到那里(我不确定是哪个)

您正在淹没消息队列,可能您需要等待更长的时间,直到您点击按钮2,直到在listblox中看到100000条为止。那么它能工作吗?不,它与此无关,task2永远不会被调用。但是,如果我使用较慢的上限,因为我喜欢100而不是100000,它会被调用。可能是windows消息泵过载了吗?但是,它确实添加了所有100000项,这很奇怪。所有项都被添加了,但是,如果它要将记录设置为offlimit,它们怎么能全部执行呢?消息队列有10000个限制,我看到了,但是通过BeginInvoke添加的所有项都被添加了,因此消息队列似乎不是限制因素。您确定Task.FromCurrentSyncronizationContext是通过windows消息实现的吗?谢谢你的另一篇文章,我会看一看。我想我知道,有两个队列,一个调用队列和一个消息队列。对BeginInvoke的每次调用都会向调用队列添加一个委托,并向消息队列添加一条“处理调用队列”消息。调用队列没有限制,消息队列有10000个限制。因此,发生的情况是,您用10000条“process”消息填充消息队列,而您的continue with从未有机会被放入(或被推离,仍然不确定发生了什么情况)消息队列。在第一个“进程”完成后,调用队列是空的,但它仍然会通过其他9999个进程消息。是的,我确信
任务。FromCurrentSyncronizationContext
使用windows消息,这是在WinForms的UI线程上运行要排队的东西的唯一方法。我同意单独的队列,但是,如果每次调用BeginInvoke都会向调用队列中添加一个委托,并向消息队列中添加一条“process invoke”消息,那么添加的项目不会超过10000个,是吗?BeginInvoke不是同步的,因为正如您所说,它只将代理添加到一个/多个队列中,但我不明白如何添加所有100000项,但ContinueWith不知何故失败了。