Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.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#异步调用UI未响应_C#_Datagridview_Asynchronous Wcf Call - Fatal编程技术网

c#异步调用UI未响应

c#异步调用UI未响应,c#,datagridview,asynchronous-wcf-call,C#,Datagridview,Asynchronous Wcf Call,这是我的要求: 单击一个按钮,我需要从数据库获取数据并填充到datagridview中,我正在使用一个函数。由于检索可能需要很长时间,并且我希望同时使用UI,因此我希望此函数在单独的线程中运行。 为此,我使用异步回调。但是在begininvoke()和endinvoke()函数之间。我没有写任何代码(我不知道写什么才能让UI响应) datagridview已正确填充,但在函数检索数据时,当我尝试访问它时,UI被阻止。如果使用循环来填充datagridview,则可以使用方法Application

这是我的要求:

单击一个按钮,我需要从数据库获取数据并填充到datagridview中,我正在使用一个函数。由于检索可能需要很长时间,并且我希望同时使用UI,因此我希望此函数在单独的线程中运行。 为此,我使用异步回调。但是在
begininvoke()
endinvoke()
函数之间。我没有写任何代码(我不知道写什么才能让UI响应)


datagridview已正确填充,但在函数检索数据时,当我尝试访问它时,UI被阻止。

如果使用
循环来填充
datagridview
,则可以使用方法
Application.DoEvents()
循环中
以使UI在填充
DataGridView
期间保持响应

更新 正如您所说的,问题不在于循环,我认为最好的方法是使用
BackgroundWorker

您可以在
BackgroundWorker的
DoWork()
事件中填充
DataGridView

您可以在代码的
按钮单击期间启动
BackgroundWorker.DoWork()
事件

我建议不要从UI线程启动长时间运行的操作。首先启动另一个线程,然后在该单独的线程中执行长时间运行的操作。完成后,使用Form.Invoke()方法将结果发布回UI。这样,UI线程就不会受到直接影响

除了手工创建另一个线程,还可以使用类似的构造


如果确实从UI线程启动长时间运行的操作,则需要定期调用Application.DoEvents()(例如,在循环中)。但是,如果长时间运行的操作是IO密集型操作(这意味着您大部分时间都在等待IO操作),那么您将无法按照自己的意愿频繁调用Application.DoEvents()。这将使UI看起来不那么灵敏或不稳定。正如我上面提到的,分离线程在这方面是一种更好的方法。

首先,我应该在UI表单本身中创建asynccallback函数,而不是在中间层(在我的例子中是DataMgr)。 另外,我应该为begininvoke函数添加最后两个参数,并在传递空值的地方添加适当的值。 应该是

MethodDelegate dlgt = new MethodDelegate(DataMgr.countIssuingEntities);
 TempValueHolder tmp = new TempValueHolder();
 AsyncCallback cb = new AsyncCallback(MyAsyncCallBack);
  IAsyncResult ar = dlgt.BeginInvoke(issueGroupId, element.ControlType, (EvaluatingEntityCombo.SelectedItem as CIQHydCore.RefData.RefDataInfo).Id, (IssuingEntityCombo.SelectedItem as CIQHydCore.RefData.RefDataInfo).Id, str1, str2,**cb,dlgt**);

在MyAsyncCallBack函数中,我们需要用从末尾检索到的值填充datgridview

,如果您使用循环填充
DataGridView
,则可以使用
Application.DoEvents()
…I“我没有使用任何循环来填充我的gridview。当我单击按钮时,相应的内容将从UI加载到gridview中。如何加载内容??项目是否一个接一个地加载?是的,它们是按行加载的。单击按钮一次,将加载一行。然后在
按钮的开头和/或结尾添加
应用程序.DoEvents()
event@I.am.WritZ那没用。它仍然会阻止DoEvents调用之间的UI。因此,在这种情况下,我应该使用backgroundworker而不是异步调用吗?如果您使用的是接受AsyncCallback委托的BeginXXX方法,那么它应该已经在单独的线程中执行该工作了。那么你就不需要使用后台工作人员了。看见但是,如果您正在处理一个阻塞操作,那么您应该使用BackgroundWorker(或者手动创建/运行一个单独的线程)。是的,这项工作是在一个单独的线程中完成的,我可以从datagridview的填充方式看出。但是,当从后端检索内容并将其添加到datagridview中时,ui已被阻止。在检索完成后,您可能正在对数据执行一些额外的工作。请发布一些用于数据检索和加载UI的代码,以便我们可以看到您正在做什么。请在问题中发布格式良好的代码。真的很难在评论中读到。