2015-01-23 4 views
0

Приложение Windows Form, выполняющее тяжелую обработку в отдельной ветке. Где-то в процессе обработки мне нужно получить некоторую обратную связь от пользователя (например, задавать некоторые вопросы о визуальном выходе на другое устройство). Если бы я сделал это в слое пользовательского интерфейса, я был бы более чем счастлив использовать контрольный Invoke и сделать это. Обработка выполняется в бизнес-слое. Я спросил каждого в бизнес-слое, никто не знает ключевое слово, например Control, Invoke, MainForm и т. Д. Как я могу уведомить основную форму и получить вход? (события? или я пропустил что-то простое?)Вызов из фоновой нити в многоуровневом приложении

+0

Вы должны реализовать его как событие или услугу, в основном спросите «кто-нибудь имеет какие-либо данные в этом процессе», позвонив в службу или уволив событие. Вы должны подумать о том, что должно произойти, если нет службы или обработчика событий, это нормально, просто нет ввода или это ошибка? Тот факт, что этот вопрос должен быть задан пользователю, который должен произойти в потоке пользовательского интерфейса, - это не то, что вы должны касаться того слоя, с которым имеете дело сейчас. –

ответ

2

Вам нужно будет передать ваш запрос вверх из бизнес-уровня, а затем вызвать его из уровня представления в пользовательском интерфейсе.

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

Мое личное предпочтение заключается в том, чтобы слои связывались напрямую друг с другом, поэтому в этом случае я бы обменивался бизнес-слоем с уровнем представления, который запрашивается с помощью ввода, а затем уровень представления будет маршализовать запрос сам вид (UI) через Invoke.

+0

Я что, заканчиваю события? – Shanadas

+0

Извините, вы можете это повторить? –

+0

Означает ли это, что мне нужно поднять событие, чтобы достичь пользовательского интерфейса, а затем вызвать? – Shanadas

2

Один из способов - создать event на вашем бизнес-уровне, с которого вы подключаетесь из своего кода управления/формы. Когда ваш элемент управления/формы получает событие, маршал обратно в поток пользовательского интерфейса, вызывающий Invoke/BeginInvoke, чтобы обновить ваш контроль (ы) соответственно.

Например, в вашем коде модели:

public class ModelFoo 
{ 
    public event EventHandler SomethingInterestingHappened; 
... 

при вызове (или трансляции) событие, это обычная практика, чтобы сделать это с помощью метода «On» (make the call thread-safe - смотри также this):

private void 
    OnSomethingInterestingHappened 
     () 
    { 
     var SomethingInterestingHappenedCopy = SomethingInterestingHappened; 
     if (SomethingInterestingHappenedCopy != null) 
     { 
      // TODO add your event data in the second args here 
      SomethingInterestingHappenedCopy (this, EventArgs.Empty); 
     } 
    } 

Тогда подписаться на него с вашего UI потока, например:

ModelFoo.SomethingInterestingHappened += SomethingInterestingHappenedHandler; 

Где:

private void SomethingInterestingHappenedHandler(object sender, EventArgs e) 
    { 
// You can call if(this.InvokeRequired) here, since 
// you might already be on the UI thread. 
// However from other threads call Invoke/BeginInvoke if wanting 
// to process synchronously/asynchronously depending on what you need and 
// you need to update a control object. 
      Invoke(new MethodInvoker(delegate 
      {... 

Я нахожу событие невероятно полезно, поскольку feels like вы развязка интерфейса от модели хорошо. События также могут быть определены на интерфейсе, поэтому код пользовательского интерфейса может говорить с чем-то абстрактным, что означает, что при необходимости можно изменить базовый тип (например, для тестирования).

Смежные вопросы