Сообщение от
UZ5DM
Да и еще вопрос - как корректно закрыть tcpClient ?
в приведенном мной примере:
Насчет закрытия. Тот пример вообщето говоря не совсем корректен с точки зрения паттерна Dispose.
Т.к. Stream в данном случае может отдизпозиться несколько раз.
Но для NetworkStream это не имеет значения, а такая реализация упрощает код - не нужно try/finally городить.
Насчет WinForms. К контролам, как выше верно указали, можно обращаться только из основного потока.
Если вы запускаете отдельный поток, то все обращения (даже к свойствам) к контролам нужно синхронизировать.
Делается это следующим образом. Нужно проверить у любого контрола свойство InvokeRequired и если оно true, то вызвать Invoke или BeginInvoke (последний вариант - асинхронный), передав ему указатель на метод (делегат), который выполнит обращение к контролу.
Например у вас на форме есть ListBox с именем lbxLog, в который вы хотите добавить строку из отдельного потока.
Для этого можно в код формы добавить такую функцию (тут this - это форма):
Код:
private void AddTextLine(string text)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new Action<string>(AddTextLine), text);
return;
}
lbxLog.Items.Add(text);
}
после этого из вашего отдельного потока можно вызвать метод AddTextLine и он безопасно добавит строку в контрол:
Код:
while (tcpClient.Connected)
{
var line = reader.ReadLine();
AddTextLine(line);
}
В данном случае вызов происходит асинхронно - через BeginInvoke.
Т.е. после вызова AddTextLine управление сразу вернется назад.
А чуть позже этот метод будет вызван из основного потока, в котором уже можно безопасно обращаться к контролам.
И таким образом добавление строки в контрол произойдет из основного потока.
Блокирующий вызов Invoke применять нужно осторожно, т.к. нужно помнить, что если форма будет закрыта, то метод никогда не вызовется из основного потока и вызов Invoke зависнет.
С BeginInvoke проще, т.к. он не ждет завершения вызова и потому после закрытия формы зависания не произойдет, вызов просто не отработает.
Для асинхронных операций можно также посмотреть в сторону Task-based асинхронное программирование, в частности async await.
Это другая концепция, но она доступна только начиная с .NET 4.5. И для начинающих думаю сложновато будет.