2015-12-22 5 views
1

в некотором классе я объявить событие следующим образом:Скрыть InvokeRequired код под классом

public delegate void UserOfflineHandler(string ip); 
public event UserOfflineHandler OnUserOffline; 

генерировать событие

void srvSomeFunc(string ip) 
{ 
    OnUserOffline(ip); 
} 

и на моей форме я создаю обработчик события

srv = new ServerClass(); 
srv.OnUserOffline += srv_OnUserOffline; 

и внутри srv_OnUserOffline Я хочу работать с ListBox, поэтому я использую делегат

delegate void UpdateUserListCallback(string s); 

private void updateUserList(string s) 
{ 
    if (listBox2.InvokeRequired) 
    { 
     UpdateUserListCallback dt = new UpdateUserListCallback(updateUserList); 
     Invoke(dt, new object[] { s }); 
    } 
    else 
    { 
     //some work with listbox 
    } 
} 

Как я могу положить это внутри своего ServiceClass, а не внутри кода формы? Таким образом, в коде формы я буду получать только что-то вроде этого:

srv.OnUserOffline += srv_OnUserOffline; 

...

void srv_OnUserOffline(string login) 
{ 
    listbox2.Add(login); 
} 
+1

Никогда, никогда * * скрытие InvokeRequired. И особенно никогда не скрывать Invoke(), это метод, который очень способен создать тупик. Вы никогда не хотите скрывать те части программы, которые стоят очень дорого (сотни микросекунд) и очень склонны к сбою программы с ужасно неустранимыми неудачами. Это неудобная правда, что вы должны очень сильно избегать использования. Он * нуждается в *, чтобы повредить, если вы спрячете его, то вы почти гарантированно создадите паршивую программу. –

+0

@ HansPassant Я с тобой на 100%. Не пытайтесь скрывать важные детали, такие как это, особенно потому, что соответствующий интерфейс должен оставаться в интерфейсе! – Leonardo

ответ

0

вы можете создать extension метод для этого и использовать его с любым контролем.

public static void InvokeIfRequired(this Control control, Action action) 
    { 

      if (control.InvokeRequired) { 
       control.Invoke(action); 
      } else { 
       action(); 
      } 
    } 

здесь, как вы будете использовать его

//I would skip this check but left up to you 
listBox2.InvokeIfRequired(() => 
{ 
    // Do anything you want with the control here 
    UpdateUserListCallback dt = new UpdateUserListCallback(updateUserList); 
    Invoke(dt, new object[] { s }); 
    }); 

и, наконец,

void srv_OnUserOffline(string login) 
{ 
     // here you are actually working with List so check Invoke only here 

     listBox2.InvokeIfRequired(() => 
     { 
       listBox2.Add(login); 
     }); 
}