Статический класс, другой поток и события - PullRequest
0 голосов
/ 14 июля 2011

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

ConnectedClient newClient; // ConnectedClient is my class storing it's socket and stream and all that.
if(NewClientConnected(out newClient)
{
...handling new client, notification, etc...
}

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

Как я могу убедиться, что событие обрабатывается основным потоком из статического неуправляемого класса? Должен ли я просто продолжать делать то, что я делаю? (фрагмент выше) Я слышу идею отношений между потребителем и производителем, для которых все равно потребуется таймер (использует собственный поток) или другой поток, если я правильно помню.

Я пытался погуглить и посмотреть здесь, но, похоже, у всех разные проблемы. Он находится в проекте библиотеки, в то время как другие проекты (мой сервер и тест клиента) ссылаются на него.

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 14 июля 2011

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

Поэтому вместо непосредственной обработки события попробуйте следующее:

// Somewhere in the form1 code:
Server.newConnectionEvent += ConnectionEVentHandler(myMethod)

public void myMethod()
{
  //Event method called from another thread
  //can only do things here that do affect the UI!
  this.Dispatcher.Invoke(CalledOnUIThread);
}

public void CalledOnUIThread()
{
  //Handle event on UI thread here
  //Can do things here that affect the UI
}

Этот код должен запускаться из класса form1, так как он использует 'this'.Таким образом, все, что вы изменяете (предположительно, вы не показывали код вашего обработчика событий), помещает фактический код, который вы хотите запустить, в отдельный метод, а затем вызываете этот отдельный метод из обработчика событий.

См. http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx для документации API по классу диспетчера.

См. Каково определение потока пользовательского интерфейса?Есть ли только один поток пользовательского интерфейса в приложении .NET? для простого объяснения потока пользовательского интерфейса.

0 голосов
/ 14 июля 2011

Взгляните на методы Control.Invoke и Control.BeginInvoke.

Control.Invoke - "Выполняет указанный делегат в потоке, которому принадлежит дескриптор основного элемента окна."

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.begininvoke.aspx

Это должно исправить ваше "исключение из другого потока"

...