如何通过事件触发功能?

时间:2010-06-24 14:58:34

标签: c# events function

我有一个应用程序,其中我希望在触发事件时在同一个线程中执行一个函数。例如:

SomeCode()
{
   // Do something...

   // Fire event to run SomeOtherCode().
}

SomeOtherCode()
{
   // Do something else...
}

我不想简单地调用该函数,因为它会保留它。 SomeOtherFuction()需要在同一个线程中执行,因为它需要访问表单控件,我需要它从事件触发器触发开始执行。我使用的是Microsoft Visual C#2008 Express Edition。感谢。

:::编辑::: 其他细节:最重要的是,我的表单应用程序的控制器花了太长时间才完成,并且从用户启动应用程序到应用程序窗口出现在显示器上时,它导致了显着的延迟。这在较快的计算机上不是问题,但在较慢的计算机上,这是一个大问题。我需要尽快退出控制器,从而允许框架绘制应用程序窗口,并在构造函数外继续初始化。 (所有基本项目仍将在构造函数中初始化。)

事件触发的函数调用将是理想的。我宁愿不使用计时器。将受影响的代码与Invoke交错在我的情况下是不切实际的,并且需要更多的时间来实现,而不是我必须处理这个问题。 一个简单的事件驱动函数调用示例就是我真正想要的。感谢。

5 个答案:

答案 0 :(得分:1)

从您的帖子看,您似乎对一些问题感到困惑。 .Net中的标准模式是事件同步运行。以下几行在执行时基本相同。

选项#1

SomeCode();
SomeOtherCode();

选项#2

SomeEvent += delegate { SomeOtherCode(); }
...
SomeCode();
SomeEvent(this,EventArgs.Empty);

如果要取消阻止UI线程并稍后运行代码,则需要使用某种机制来延迟SomeOtherCode函数的运行。在WinForms应用程序中执行此操作的最简单方法是使用WinForms Timer实例。这将在稍后的时间点在UI线程上引发一个您可以响应的事件。在此期间,它也不会阻止UI线程,从而允许表单继续处理。

答案 1 :(得分:0)

您似乎要求稍后运行SomeOtherCode()

您可以调用BeginInvoke(来自UI线程或任何其他线程)将函数排入队列以在下一个消息循环中运行:

BeginInvoke(new Action(SomeOtherCode));

答案 2 :(得分:0)

似乎您希望向暴露SomeCode方法的类添加事件。然后,实现SomeOtherCode方法的类将附加一个调用SomeOtherCode方法的事件处理程序。

在一个类中完成此操作是完全可行的,以防您有某种状态模型,您希望根据其他逻辑添加/删除调用。

答案 3 :(得分:0)

我认为您希望将SomeOtherCode放入TaskBackgroundWorker,然后与UI线程同步以向其发送更新。

我最近发布了on my blog a class,这使得从Task更新UI与从BGW一样简单。我建议使用Task而不是BackgroundWorker

答案 4 :(得分:0)

Simialr对Stephen的说法,我建议您将尽可能多的初始化代码移动到后台线程或任务。让后台线程尽可能多地工作,然后通过Action<>'将必要的窗口更新发送到您的UI线程。这是一些快速的伪样本代码:

protected void LoadMyListInBackground(object state)
{
   List<string> myList = Databse.FetchMyList(myParameters); // This take a while, so the UI thread isn't waiting

   ShowMyList(myList);
}

protected void ShowMyList(List<string> theList)
{
  if(InvokeRequired)
    Invoke(new Action<List<string>>(ShowMyList, theList);
  else
  {
    foreach(string item in theList)
      myListBox.Items.Add(item);
  }
}

在此示例中,UI线程可以自由地绘制窗口,而后台线程可以执行冗长的数据库工作。问题是,即使您在构造函数之外触发事件,并且该事件发生在UI线程上并且需要很长时间,用户可能会看到窗口,但该窗口将“冻结”并且可能看起来像'坠毁'给用户。这种技术可以防止这种情况,并提供更好的用户体验。