c#async调用UI无响应

时间:2012-05-17 05:35:57

标签: c# datagridview asynchronous-wcf-call

这是我的要求:

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

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

3 个答案:

答案 0 :(得分:1)

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

您可以使用像BackgroundWorker这样的构造。

,而不是手动创建另一个线程

如果从UI线程开始长时间运行操作,则需要定期调用Application.DoEvents()(例如在循环内)。但是,如果长时间运行操作是IO密集型操作 - 这意味着您大多数时间都在等待IO操作 - 那么您将无法根据需要随时调用Application.DoEvents()。这将使UI看起来不那么敏感或不稳定。正如我上面提到的,单独的线程在这方面是更好的方法。

答案 1 :(得分:0)

如果您使用loop填充DataGridView,则可以使用Application.DoEvents()内的方法loop让您的用户界面保持响应状态DataGridView

更新

正如你所说的问题不是循环,我认为最好的方法是使用BackgroundWorker类。

您可以在[{1}}

DataGridView事件中填充DoWork()的位置

您可以在代码BackgroundWorker活动期间开始BackgroundWorker.DoWork()活动!

答案 2 :(得分:0)

首先,我应该在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

相关问题