0

这是我的要求:

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

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

4

3 回答 3

1

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

除了手动创建另一个线程,您还可以使用BackgroundWorker之类的构造。

如果您确实从 UI 线程开始长时间运行的操作,则需要定期调用 Application.DoEvents()(例如在循环内)。但是,如果长时间运行的操作是 IO 密集型的——这意味着你大部分时间都在等待 IO 操作——那么你就不会像你想要的那样频繁地调用 Application.DoEvents()。这将使 UI 看起来反应迟钝或生涩。正如我上面提到的,单独的线程在这方面是一种更好的方法。

于 2012-05-17T05:47:36.967 回答
0

如果您使用 a来loop填充您的.DataGridViewApplication.DoEvents()loopDataGridView

更新

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

如果发生以下情况,您可以DataGridView在哪里填充DoWork()BackgroundWorker

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

于 2012-05-17T05:47:19.193 回答
0

首先,我应该在 UI 表单本身中创建异步回调函数,而不是在中间层,在我的例子中是 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

于 2012-05-18T08:34:02.860 回答