2013-08-13 2 views
1

Итак, у меня есть код из GUI-программы, который вызывает делегата через метод control.invoke, и теперь я хочу сделать это в консоли.Вызовите без контроля?

Это код:

public class upnpforwarder 
{ 
    List<INatDevice> devices = new List<INatDevice>(); 

    public upnpforwarder() 
    { 
     //Hook into the events so you know when a router has been detected or has gone offline 
     NatUtility.DeviceFound += DeviceFound; 

     //Start searching for upnp enabled routers 
     NatUtility.StartDiscovery(); 
    } 

    delegate void AddDeviceDelegate(INatDevice device); 
    delegate void RemoveDeviceDelegate(INatDevice device); 

    // Adding devices to the list and listbox 
    private void AddDevice(INatDevice device) 
    { 
     if (!devices.Contains(device)) 
     { 
      devices.Add(device); 
      IPAddress external = device.GetExternalIP(); 
      Mapping[] maps = device.GetAllMappings(); 

      //complicated stuff because the library only allows to display some data via .ToString() as far as I know 
      string str = device.ToString(); 
     } 
    } 


    // Event that handles a new found device 
    private void DeviceFound(object sender, DeviceEventArgs args) 
    { 
     //Make it thread-safe 
     AddDeviceDelegate AddDeviceInstance = new AddDeviceDelegate(this.AddDevice); 

     this.Invoke(AddDeviceInstance, new object[] { args.Device }); 
    } 

Каков наилучший альтернативный метод: this.Invoke(AddDeviceInstance, new object[] { args.Device });?

+1

Invoke используется, чтобы убедиться, вызов происходит в потоке пользовательского интерфейса (а не фоновый поток). Если у вас нет пользовательского интерфейса, вам не нужно ничего перемещать в поток пользовательского интерфейса. Просто вызовите метод. –

+0

Использование control.Invoke применимо только в многопоточной ситуации. Обычно, когда есть один поток пользовательского интерфейса и один или несколько рабочих потоков. У вас несколько потоков в консольной версии программы? – RenniePet

ответ

0

1) «Invoke» не обеспечивает безопасность кода. Вероятно, вы путали это с проблемой доступа к элементу управления UI .NET из потока, отличного от потока пользовательского интерфейса.

2) В чем смысл наличия «контроля» в смысле интерфейса в консольном приложении? Альтернативой было бы просто вызвать метод.

Если вы пытаетесь сделать это асинхронно, самым простым способом является использование TPL.

+0

Функция делегирования гарантирована для потокобезопасности. – PoweredByOrange

+0

Но они не выполняются в критическом разделе, поэтому они не делают исполняемый поток кода безопасным. – BartoszKP

+0

http://stackoverflow.com/questions/6349125/are-c-sharp-delegates-thread-safe – PoweredByOrange

0

Control.Invoke вызывается в потоке пользовательского интерфейса (поток, которому принадлежит элемент управления). По сути, это синхронно в вашем примере.

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

Task.Factory.StartNew(() => ..call delegate here ..); 
Смежные вопросы