C #: Как я могу элегантно и упрощенно совершать перекрестные вызовы? - PullRequest
3 голосов
/ 06 марта 2009

У меня есть tcp-сервер, который, когда клиент подключается, создает новый поток и добавляет их к нему, но каждый раз, когда я пытаюсь получить доступ к информации о соединении или что-нибудь о нем, скажем, даже с учетом количества клиентов подключено, я получаю перекрестное незаконное исключение или что-то в этом роде.

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

Есть ли элегантный или упрощенный способ сделать это? мне нужно научиться делать что-то еще в первую очередь? или я просто усложняю вещи? любые предложения, ссылки или советы наиболее ценны и приняты.

Ответы [ 4 ]

1 голос
/ 06 марта 2009

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

Что касается операций с несколькими потоками, особенно операции с потоками пользовательского интерфейса, я считаю SynchronizationContext очень полезной в ситуациях, когда вы хотите перенаправить вызов из потока без пользовательского интерфейса в поток пользовательского интерфейса. См. эту статью для более глубокого обсуждения.

0 голосов
/ 06 марта 2009

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

Скажите, что вы хотите добавить элемент в список с именем ListBoxLog. Этот код справился бы с любой задачей:

ListBoxLog.Invoke((MethodInvoker)delegate { ListBoxLog.Items.Add("Done"); });

Существует также свойство, которое нужно проверить. InvokeRequired, вы можете проверить, является ли вызов необязательным. Обычно вы проверяете это свойство в функции, которая может вызываться как основным потоком пользовательского интерфейса, так и любым фоновым потоком.

Вы также можете использовать BeginInvoke, как я это делал с Invoke. BeginInvoke полностью асинхронный и не ожидает завершения кода в делегате.

0 голосов
/ 06 марта 2009

Есть много примеров онлайн, чтобы помочь вам: http://www.google.com/search?q=tcp+server+multi+thread

При использовании C # Runtime Concurrency and Coordination Runtime (CCR) также содержит пример реализации многопоточного tcp сервера. CCR позволяет гораздо лучшую парадигму для реализации параллельной обработки, он значительно упрощает стандартный многопоточный код.

0 голосов
/ 06 марта 2009

Использование делегатов и событий .

Это был бы мой лучший ответ.

http://www.codeproject.com/KB/cs/Cross_thread_Events.aspx

...