C# 在线程中创建窗口的问题
我想用C#编写一个简单的聊天程序,创建了一个线程用于监听一个端口,每当有对话请求的时候就需要创建一个对话窗口,但是创建出来的窗口一直没有反应,像程序死了一样。求高手解答。...
我想用C#编写一个简单的聊天程序,创建了一个线程用于监听一个端口,每当有对话请求的时候就需要创建一个对话窗口,但是创建出来的窗口一直没有反应,像程序死了一样。求高手解答。监听线程的代码如下:
public static void Doword()
{
string ip = "127.0.0.1";
TcpListener myListener = new TcpListener(IPAddress.Parse(ip), 5555);
myListener.Start();
while (true)
{
try
{
TcpClient myclient = myListener.AcceptTcpClient();
Thread.Sleep(100);
form_Chat newchat = new form_Chat(myclient);
newchat.Show();
}
catch (ThreadAbortException e)
{
Thread.ResetAbort();
}
}
}
一楼: 我试过这种方法了,但是在newchat.show()完成之后线程就结束了,打开的窗口闪一下就没得勒 展开
public static void Doword()
{
string ip = "127.0.0.1";
TcpListener myListener = new TcpListener(IPAddress.Parse(ip), 5555);
myListener.Start();
while (true)
{
try
{
TcpClient myclient = myListener.AcceptTcpClient();
Thread.Sleep(100);
form_Chat newchat = new form_Chat(myclient);
newchat.Show();
}
catch (ThreadAbortException e)
{
Thread.ResetAbort();
}
}
}
一楼: 我试过这种方法了,但是在newchat.show()完成之后线程就结束了,打开的窗口闪一下就没得勒 展开
4个回答
展开全部
LZ,你这个逻辑就不太对啊。
监听线程就是用来监听的,需要不断地执行一个循环来实现“监听”,它根本就没有功夫来处理UI方面的东西(也就是执行消息循环)。比如你这个监听线程,大部分时间都会阻塞在TcpClient myclient = myListener.AcceptTcpClient();这里,根本没法处理消息循环(而且你这个监听线程根本就没有消息循环)
你应该是在主UI线程上创建窗体。就是通过invoke方法让创建和显示窗体的代码在主UI线程上执行(你先要想办法得到主UI线程上一个控件的引用)假设你有一个主窗体的引用MainForm,代码大概就是这样:
MainForm.Invoke(Sub()
Dim f As New Form1
f.Show()
End Sub)
这是VB.NET的代码(我只会写VB.NET,C#只会看),MainForm.Invoke() VB/C#都是这样调用。后面接受一个委托,由于代码比较少,我这里直接用的Lambda表达式。
一般有一条UI线程就够了。如果一定要每个聊天窗口都有一条UI线程的话,应该在创建窗口的线程上调用Application.Run。这样线程才会执行消息循环,否则就像你说的那样,两句代码一执行完,线程就结束退出,窗口也就没了。代码:
Dim t As New Thread(Sub()
Dim f As Form
f = New Form1
Application.Run(f)
End Sub)
t.Start()
【注意】是要你在“监听线程”中再创建一条线程,并在那条线程上创建窗体并开始消息循环。不是在“监听线程”中创建窗体并执行消息循环。
总之窗体不能在监听线程里。要么你Invoke到主UI线程上,要么在新的线程上创建窗体。如果在新的线程上创建窗体,一定要用Application.Run来展开消息循环,不然线程两句话一执行完就没了。而且就算你用点奇巧淫技让线程不退出,没有消息循环,窗体也会“没有响应的”
监听线程就是用来监听的,需要不断地执行一个循环来实现“监听”,它根本就没有功夫来处理UI方面的东西(也就是执行消息循环)。比如你这个监听线程,大部分时间都会阻塞在TcpClient myclient = myListener.AcceptTcpClient();这里,根本没法处理消息循环(而且你这个监听线程根本就没有消息循环)
你应该是在主UI线程上创建窗体。就是通过invoke方法让创建和显示窗体的代码在主UI线程上执行(你先要想办法得到主UI线程上一个控件的引用)假设你有一个主窗体的引用MainForm,代码大概就是这样:
MainForm.Invoke(Sub()
Dim f As New Form1
f.Show()
End Sub)
这是VB.NET的代码(我只会写VB.NET,C#只会看),MainForm.Invoke() VB/C#都是这样调用。后面接受一个委托,由于代码比较少,我这里直接用的Lambda表达式。
一般有一条UI线程就够了。如果一定要每个聊天窗口都有一条UI线程的话,应该在创建窗口的线程上调用Application.Run。这样线程才会执行消息循环,否则就像你说的那样,两句代码一执行完,线程就结束退出,窗口也就没了。代码:
Dim t As New Thread(Sub()
Dim f As Form
f = New Form1
Application.Run(f)
End Sub)
t.Start()
【注意】是要你在“监听线程”中再创建一条线程,并在那条线程上创建窗体并开始消息循环。不是在“监听线程”中创建窗体并执行消息循环。
总之窗体不能在监听线程里。要么你Invoke到主UI线程上,要么在新的线程上创建窗体。如果在新的线程上创建窗体,一定要用Application.Run来展开消息循环,不然线程两句话一执行完就没了。而且就算你用点奇巧淫技让线程不退出,没有消息循环,窗体也会“没有响应的”
展开全部
form_Chat newchat = new form_Chat(myclient);
newchat.Show();
把这个地方封装成一个函数,然后每接受一个连接创建一个线程 ,执行这个函数
百度hi,详聊
newchat.Show();
把这个地方封装成一个函数,然后每接受一个连接创建一个线程 ,执行这个函数
百度hi,详聊
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
貌似没有直接的办法。
你的问题也有点前后矛盾。
窗口句柄、进程句柄、主线程句柄是不同出概念。
但这些都可以通过枚举获得。如果是主线程句柄,你可以枚举系统中的进程,找到你所需要的进程句柄,然后通过进程句柄获得主线程句柄。
如果是窗口,可以通过枚举系统中所有的窗口,逐个比较,得到你所需要的窗口句柄。当然如果窗口特征很明显,还可以用FindWindow省去逐个枚举的麻烦。
你的问题也有点前后矛盾。
窗口句柄、进程句柄、主线程句柄是不同出概念。
但这些都可以通过枚举获得。如果是主线程句柄,你可以枚举系统中的进程,找到你所需要的进程句柄,然后通过进程句柄获得主线程句柄。
如果是窗口,可以通过枚举系统中所有的窗口,逐个比较,得到你所需要的窗口句柄。当然如果窗口特征很明显,还可以用FindWindow省去逐个枚举的麻烦。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
public Form1()
{
InitializeComponent();
IPAddress ip = IPAddress.Parse("172.30.32.128");
IPEndPoint ipe = new IPEndPoint(ip, 3602);
shou.Bind(ipe);
shou.Listen(10);
Thread xian = new Thread(new ThreadStart(bin));
xian.IsBackground = true;
xian.Start();
}
public void bin()
{
while(true){
Thread.CurrentThread.IsBackground = true;//后台运行
Socket newshou = shou.Accept();
recString1 = "收到" + newshou.RemoteEndPoint.ToString() + "的信息!";
byte[] da = new byte[1024];
int da_len;
string da_str;
da_len = newshou.Receive(da);
da_str = Encoding.UTF8.GetString(da, 0, da_len);
bin1(da_str);
newshou.Close();
}
这是我自己做的聊天程序中的一段,希望对你有帮助.
其实最主要的是让监听线程处于后台运行,线程名.IsBackground = true;
{
InitializeComponent();
IPAddress ip = IPAddress.Parse("172.30.32.128");
IPEndPoint ipe = new IPEndPoint(ip, 3602);
shou.Bind(ipe);
shou.Listen(10);
Thread xian = new Thread(new ThreadStart(bin));
xian.IsBackground = true;
xian.Start();
}
public void bin()
{
while(true){
Thread.CurrentThread.IsBackground = true;//后台运行
Socket newshou = shou.Accept();
recString1 = "收到" + newshou.RemoteEndPoint.ToString() + "的信息!";
byte[] da = new byte[1024];
int da_len;
string da_str;
da_len = newshou.Receive(da);
da_str = Encoding.UTF8.GetString(da, 0, da_len);
bin1(da_str);
newshou.Close();
}
这是我自己做的聊天程序中的一段,希望对你有帮助.
其实最主要的是让监听线程处于后台运行,线程名.IsBackground = true;
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询