В MSDN по этой ссылке можно почитать о том, как предлагают останавливать потоки.
http://msdn.microsoft.com/ru-ru/library/7a2f3ay4(v=vs.90).aspx
Создаётся класс, в котором есть метод, который присваивает переменной значение true, заставляя прерываться цикл в thread'е, затем выполняют <имя_нитки>.Join() и она останавливается.
Правильно ли я понимаю, что если в теле нитки находится лишь две строки, не являющиеся циклом и выполняющиеся лишь однажды, то этот поток удалится сразу после выполнения для него Join'а, безо всяких дополнений?
Тогда дополнительный вопрос, если в этом я правильно разобрался, то могу ли я чуть позже в программе снова вызывать этот поток?
Если нужно, то приведу код в примечании
Примечание:
Я пытаюсь реализовать этот (http://round-angle-net.blogspot.ru/2010/09/tcpip-c.html) пример в Windows Forms.
Вывод пытался осуществить в textBox1, но программа "висла", тогда я задумался о том, что зависающий интерфейс - это неправильно и начал искать инфу о том, как это контрится; нашёл - потоки. А вот применить пока не получается, если я пытаюсь в потоках производить вывод в нужных местах, программа стопорится и не работает после подключения (оно происходит, судя по пустому экрану без ошибок в cmd, после ввода telnet 192.168.0.41 2200), а если так, как оно сейчас, то просто нет никакого вывода, хотя программа отрабатывает.
Хочу, чтобы это работало с потоками :)
Т.е. сообщение отсылалось клиенту и при этом textBox1 выполнял роль консоли из примера.
[CODE C#]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Threading;
namespace ClientMess
{
public class Show
{
private Form1 Form1;
private string s;
public Show(Form1 Form2, string s2)
{
Form1 = Form2; s = s2;
}
public void set_s(string s2)
{
s = s2;
}
public void SS()
{
Form1.textBox1.Text = Form1.textBox1.Text + s;
Form1.textBox1.Text = Form1.textBox1.Text + Environment.NewLine;
}
}
public class Serv
{
public static void Connect()
{
Form1 Form1 = new Form1();
ASCIIEncoding encoding = new ASCIIEncoding();
Show sh = new Show(Form1, "");
Thread t = new Thread(
new ThreadStart(sh.SS));
Byte[] message = encoding.GetBytes("Ya nemnogo zanyat, prihodite popozhe");
try
{
Form1.textBox1.Text = "Начало работы.";
Form1.textBox1.Text = Form1.textBox1.Text + Environment.NewLine;
IPAddress localAddress = IPAddress.Parse("192.168.0.41");
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndpoint = new IPEndPoint(localAddress, 2200);
listenSocket.Bind(ipEndpoint);
listenSocket.Listen(1);
while (true)
{
sh.set_s("Сервер ожидает " + ipEndpoint);
sh.SS();
//sh.set_s("Сервер ожидает " + listener.LocalEndpoint);
//Thread.Sleep(1);
//t.Start();
//t.Join(2);
Socket handler = listenSocket.Accept();
sh.set_s("Принято соединение от " + handler.RemoteEndPoint);
sh.SS();
//sh.set_s("Принято соединение от " + client.Client.RemoteEndPoint);
//Thread.Sleep(1);
//t.Start();
//t.Join(2);
sh.set_s("Отправляем сообщение...");
sh.SS();
//Thread.Sleep(1);
//t.Start();
//t.Join(2);
handler.Send(encoding.GetBytes("Я занят"));
sh.set_s("Закрытие соединения");
sh.SS();
//Thread.Sleep(1);
//t.Start();
//t.Join(2);
handler.Close();
}
}
catch (Exception e)
{
Form1.textBox1.Text = Form1.textBox1.Text + "Произошла ошибка " + e.Message;
Form1.textBox1.Text = Form1.textBox1.Text + Environment.NewLine;
}
}
}
}
[/CODE]
Примечание:
А это остальной код:
[CODE C#]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Threading;
namespace ClientMess
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread StaticCaller = new Thread(
new ThreadStart(Serv.Connect));
StaticCaller.Start();
}
}
}
[/CODE]
Примечание:
Microsoft Visual Studio 2010
Версия 10.0.30319.1 RTMRel
Платформа Microsoft .NET Framework
Версия 4.5.50709 RTMRel
Примечание:
Я внял совету г-на PetSerAl и теперь куски вызова внутреннего потока выглядят следующим образом:
[CODE C#]
//sh.SS();
//sh.set_s("Сервер ожидает " + listener.LocalEndpoint);
//Thread.Sleep(1);
Thread t = new Thread(
new ThreadStart(sh.SS));
t.Start();
t.Join(2);
[/CODE]
Программа работает.
Но я понял это, лишь приведя тело метода SS к следующему виду:
[CODE C#]
public void SS()
{
MessageBox.Show(s);
Form1.textBox1.Text = Form1.textBox1.Text + s;
Form1.textBox1.Text = Form1.textBox1.Text + Environment.NewLine;
}
[/CODE]
Однако, textBox1 так и не стал альтернативой консоли, очевидно, что нужно было передать экземпляр уже существующей формы в эти потоки, а не создавать внутри них новый.
Это уже совсем другая история :)