Как функция может быть вызвана событием? - PullRequest
0 голосов
/ 24 июня 2010

У меня есть приложение, в котором я хотел бы, чтобы функция выполнялась в том же потоке, когда происходит событие.Например:

SomeCode()
{
   // Do something...

   // Fire event to run SomeOtherCode().
}

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

Я не хочу просто вызывать функцию, потому что она будет держать вещи.SomeOtherFuction() необходимо выполнить в том же потоке, потому что ему нужен доступ к элементам управления формы, и мне нужно, чтобы он начал выполнение с срабатывания триггера события.Я использую Microsoft Visual C # 2008 Express Edition.Спасибо.

::: РЕДАКТИРОВАТЬ ::: Дополнительные сведения: Суть в том, что процесс сжатия моего приложения формы занимает слишком много времени, и это вызывает значительную задержку с момента запуска пользователяприложение, когда окно приложения появляется на дисплее.Это не проблема на более быстрых компьютерах, но на более медленных компьютерах это большая проблема.Мне нужно выйти из устройства сжатия как можно скорее, что позволит каркасу нарисовать окно приложения и продолжить инициализацию за пределами конструктора.(Все существенные элементы будут по-прежнему инициализироваться внутри конструктора.)

Инициированный вызовом функции вызов будет идеальным.Я бы предпочел не использовать таймер.Чересстрочная развертка кода с Invokes нецелесообразна в моей ситуации и потребует гораздо больше времени для реализации, чем я должен работать над этим. Простой пример вызова управляемой событиями функции - это все, что я действительно ищу .Спасибо.

Ответы [ 5 ]

1 голос
/ 24 июня 2010

Судя по вашим сообщениям, вы путаете несколько вопросов. Стандартный шаблон в .Net предназначен для синхронного запуска событий. Следующие строки практически идентичны с точки зрения того, когда они выполняются.

Вариант № 1

SomeCode();
SomeOtherCode();

Вариант № 2

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

Если вы хотите разблокировать поток пользовательского интерфейса и запустить код позже, вам нужно будет использовать некоторый механизм, чтобы задержать запуск функции SomeOtherCode. Самый простой способ сделать это в приложении WinForms - это использовать экземпляр WinForms Timer. Это вызовет событие в потоке пользовательского интерфейса в более поздний момент времени, на который вы можете ответить. Он также не заблокирует поток пользовательского интерфейса в течение этого времени, позволяя вашей форме продолжить обработку.

0 голосов
/ 24 июня 2010

Simialr к тому, что сказал Стивен, я бы порекомендовал вам перенести как можно большую часть этого кода инициализации в фоновый поток или задачу. Позвольте фоновому потоку выполнить как можно больше работы, а затем отправьте необходимые обновления окна в ваш поток пользовательского интерфейса через Action <>. Вот небольшой пример кода psuedo:

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);
  }
}

В этом примере поток пользовательского интерфейса может продолжать рисовать ваше окно, пока фоновый поток выполняет длительную работу базы данных. Проблема в том, что даже если вы запускаете событие вне вашего конструктора, и это событие происходит в потоке пользовательского интерфейса и занимает много времени, пользователь может увидеть окно, но это окно будет «зависать» и, возможно, будет упал "для пользователя. Этот метод предотвращает это и обеспечивает лучший пользовательский опыт.

0 голосов
/ 24 июня 2010

Похоже, вы захотите добавить событие в класс, который предоставляет метод SomeCode.Затем класс, реализующий метод SomeOtherCode, прикрепит обработчик события, который вызывает метод SomeOtherCode.

Совершенно целесообразно сделать это в одном классе, если у вас есть какая-то модель состояния, в которой вы хотитедобавить / удалить звонок в зависимости от какой-то другой логики.

0 голосов
/ 24 июня 2010

Я думаю, вы хотите поместить SomeOtherCode в Task или BackgroundWorker, который затем будет синхронизироваться с потоком пользовательского интерфейса для отправки обновлений.

Я недавно разместил в своем блогекласс , который делает обновление пользовательского интерфейса с Task таким же простым, как с BGW.Я рекомендую использовать Task вместо BackgroundWorker.

0 голосов
/ 24 июня 2010

Вы, похоже, просите запустить SomeOtherCode() позже .

Вы можете позвонить BeginInvoke (либо из потока пользовательского интерфейса, либо из любого другого потока) поставить в очередь функцию для запуска во время следующего цикла сообщений:

BeginInvoke(new Action(SomeOtherCode));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...