Ответы пользователя по тегу Многопоточность
  • Как организовать завершение отдельно запущенного треда в C#, если в нем сокет слушает сеть?

    Illivion
    @Illivion
    В принципе, все уже изложили выше, резюмирую:

    Вариантов как таковых два:

    1. Использовать APM и метод BeginAccept. Оптимальный выбор. Так же можно обернуть в TAP через wrapper и использовать с await.

    2. Вынести ссылку на сокет в глобальное пространство и оставить синхронный метод в потоке. Но при выходе закрывать или освобождать сокет из другого потока, а этому потоку назначить IsBackground (подробнее тут) чтобы даже при некорректном выходе поток не завис.
    Ответ написан
    1 комментарий
  • Очередной вопрос про фоновое выполнение функций?

    Illivion
    @Illivion
    Для операций в фоне советую использовать асинхронные операции. Если это сеть, то, например BeginSend и BeginWrite. В колбэках прописываем реакцию в GUI. Для того, чтобы операция выполнилась в GUI-потоке используем SynchronizationContext. Вот такой простой пример:

    public partial class SimpleForm : Form
        {
            private readonly SynchronizationContext _context;
    
            private readonly TcpListener _serverListener;
    
            private int _connectionsCount;
    
            public SimpleForm()
            {
                InitializeComponent();
    
                // Зафиксировали GUI-поток
                _context = SynchronizationContext.Current;
    
                // Включаем ожидание входящих соединений
                _serverListener = new TcpListener(IPAddress.Loopback, 30000);
                _serverListener.Start();
                _serverListener.BeginAcceptTcpClient(AcceptCallback, null);
            }
    
            private void AcceptCallback(IAsyncResult ar)
            {
                // Поймали соединение. Завершаем.
                var client = _serverListener.EndAcceptTcpClient(ar);
    
                // Сообщаем о новом подключении.
                AddConnection();
            }
    
            private void AddConnection()
            {
                // Увеличиваем счетчик подключений
                Interlocked.Add(ref _connectionsCount, 1);
    
                // Сообщаем лейблу на форме новое значение. Используем GUI-поток, ибо в Callback'е находимся в чужом потоке из пула.
    
                _context.Post(state => { lbConnCount.Text = _connectionsCount.ToString(); }, null);
            }
        }
    
    Ответ написан
    1 комментарий