Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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
.net 任何GUI更新(即使是异步的)是否总是阻止我的GUI,例如使用两个相邻的表单?_.net_Winforms_Asynchronous_.net 4.0 - Fatal编程技术网

.net 任何GUI更新(即使是异步的)是否总是阻止我的GUI,例如使用两个相邻的表单?

.net 任何GUI更新(即使是异步的)是否总是阻止我的GUI,例如使用两个相邻的表单?,.net,winforms,asynchronous,.net-4.0,.net,Winforms,Asynchronous,.net 4.0,我们有一个场景,在一个WinForms应用程序(.NET 4.0)中,两个表单相邻显示。一种形式的更改应触发另一种形式的更改。假设在一个表单中加载了联系人A,则另一个表单应显示新选定联系人的联系人详细信息。例如,当大量数据加载到网格中时,对GUI的这些更改可能需要一点时间 理想情况下,我希望更新一个表单而不阻塞另一个表单 我尝试使用后台工作程序,让GUI更新工作在dowork(通过InvokeRequired)或已完成的事件中进行,但没有效果:在一种形式中更新GUI的工作似乎会阻止另一种形式中的

我们有一个场景,在一个WinForms应用程序(.NET 4.0)中,两个表单相邻显示。一种形式的更改应触发另一种形式的更改。假设在一个表单中加载了联系人A,则另一个表单应显示新选定联系人的联系人详细信息。例如,当大量数据加载到网格中时,对GUI的这些更改可能需要一点时间

理想情况下,我希望更新一个表单而不阻塞另一个表单

我尝试使用后台工作程序,让GUI更新工作在dowork(通过InvokeRequired)或已完成的事件中进行,但没有效果:在一种形式中更新GUI的工作似乎会阻止另一种形式中的任何事件—正如我所说—占用时间的主要是GUI工作,而不是像复杂的计算,可以在后台完成

如果不阻止另一个表单,我就不能更新一个表单,这是意料之中的吗?有什么解决办法吗?(我读过一点关于.net 4.5的async关键字的内容——例如,它的行为是否相同?)


欢迎任何意见

快速示例。你没有指定语言,所以是C语言

您可能不需要像第一百个项目那样快速更新。您可能只需要每1000或100000次。在屏幕响应性和处理的项目之间取得良好的平衡之前,您可以一直使用它


您可能还需要考虑的一些背景信息:

为什么大多数UI框架都是单线程的


作为一个很好的遵循规则:“使用任务来处理UI线程和其他线程之间的交互”

除非你已经做了一些事情来使用两个线程,否则你只有一个UI线程,所以在一个线程上发生的任何事都会阻止任何人在该线程上做更多的事情,直到它完成了你要求它做的事情。您可以在不同的线程上创建表单;但是,您必须处理到这些线程的来回封送(不一定是免费的)。如果从工作线程中收集的数据更新网格已经导致不可接受的延迟,那么您只是做错了。这类似于谷歌在一个网页上显示所有查询匹配项。用户也非常不友好。创建可用的UI,您的程序就会自动停止吸泥。@PeterRitchie谢谢,您对单一UI线程的评论是有意义的。@HansPassant说得很公平,您可能在这里提出了一个很好的观点!如果加载的数据太多,导致UI响应受阻,那么您可能需要考虑一下自己在做什么,以及是否有更好的方法将数据处理成更小的数据块。也就是说,在WinForms中,您可以执行
DoEvents()
来释放一个表单的处理时间,以允许另一个表单执行一些工作。如果要加载大量数据,我会每处理X个数据元素添加
DoEvents()
。如果你需要更多的细节,请告诉我。我会给你举个例子。
private void someLongRunningProcess()
{
  // Set this to how many items you have to process
  // This could come from a List of objects, numbers of records, etc.
  int qtyremaining = 5000;

  do
  {
    // Process one item
    ...

    // Every hundredth item, release the thread
    if ((qtyremaining % 100) == 0)
    {
      System.Windows.Forms.Application.DoEvents();
    };

    // Decrement your stack size
    qtyremaining--;
  } while (qtyremaining > 0);
}