2016-08-05 5 views
1

Попытка обернуть мою голову вокруг того, почему Windows Form, реализующая обратный вызов, не работает.Обратные вызовы в SynchronizationContext

То, что я пытаюсь сделать:

  • кнопка нажата, и услуга называется.
  • Служба перезванивает к форме (функция имеет IsOneWay = истина)
  • ГИП обновления формы соответственно

Имея UseSynchronizationContext на лжи и вызов Invoke на членах GUI работает отлично:

[CallbackBehavior(UseSynchronizationContext = false)] 
public class DeliveryClient : System.Windows.Forms.Form, ICallback 
{   
     public void ServiceCallback(string system, string state, string extraInfo) 
     { 
      if (state == "start") 
      { 
       Invoke((MethodInvoker)delegate { picBox.Visible = true; }); 
      } 
      else 
      { 
       Invoke((MethodInvoker)delegate { picBox.Visible = false; }); 
      } 
     } 
} 

Но UseSynchronizationContext = истина и прямой вызов членов нет:

[CallbackBehavior(UseSynchronizationContext = true)] 
public class DeliveryClient : System.Windows.Forms.Form, ICallback 
{   
     public void ServiceCallback(string system, string state, string extraInfo) 
     { 
      if (state == "start") 
      { 
       picBox.Visible = true; 
      } 
      else 
      { 
       picBox.Visible = false; 
      } 
     } 

Ни делает с помощью SyynchronizationContext буквально

SynchronizationContext.Current.Send(_=> picBox.Visible = true, null); 

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

ответ

1

Ваш Form класс действительно реализация вашего WCF клиента службы обратного вызова, , как WCF знает (то есть не только то, что вы делегировать от клиента WCF)? Если нет, то вы поместите атрибут [CallbackBehavior] в неправильное место. В документации говорится:

CallbackBehaviorAttribute должен быть применен к классу, который реализует контракт обратного вызова

Если это реализация вашего клиента обратного вызова, то без хорошего Minimal, Complete, and Verifiable code example Боюсь, не сможет сказать, почему атрибут не имеет ожидаемого эффекта. Но у меня есть : сможет сказать, что если это действительно так, ваш код плохо разработан. Объединение вашего пользовательского интерфейса со службой обратного вызова клиентского сервиса нарушает ряд принципов ООП для здорового кода, но, самое главное, принцип Separation of Concerns.

Насколько это идет:

SynchronizationContext.Current.Send(_=> picBox.Visible = true, null); 

Это не так, как вы должны использовать SynchronizationContext. Свойство Current возвращает контекст для текущего потока. К тому времени, когда вам нужно позвонить Send(), слишком поздно получить контекст. Вам необходимо сохранить SynchronizationContext.Current при создании объекта в потоке, в котором вы хотите делегировать делегаты Send() (и, конечно, этот поток должен иметь полезный контекст, например, найденный в основном потоке пользовательского интерфейса программы Winforms).

Если приведенное выше не дает вам достаточной информации, чтобы получить код, пожалуйста, улучшите вопрос, предоставив хороший MCVE, который надежно воспроизведет проблему.

+0

обратное обращение корректно да, форма реализует обратный вызов.Я попытаюсь сохранить SynContext сейчас – Laurijssen

+0

Действительно, сохранение SynContext после работы InitializeComponent – Laurijssen

+0

Я не согласен с ситуацией на самом деле. Форма, использующая обратный вызов, единственная цель которого - обновить форму, выглядит нормально для меня – Laurijssen

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