c# - 在 Form2() 中启动“新线程 IsBackground = true”并陷入 while(true) 循环
问题描述
我正在制作一个多线程聊天服务器和聊天客户端。客户端有一个名为 Login 的 Form1 和一个名为 MainProgram 的 Form2。以下代码来自“登录”。我想要做的是从登录过渡到主程序......
MainProgram mP = new MainProgram(clientSocket, username);
mP.Closed += (s, args) => this.Close();
this.Hide();
mP.ShowDialog();
mP.Show();
... 然而。分配 mP 时MainProgram mP = new MainProgram(clientSocket, username);
,代码会卡在此处指定的线程中:
public MainProgram(TcpClient c, string u)
{
InitializeComponent();
try
{
serverStream = c.GetStream();
clientSocket = c;
username = u;
new Thread(Receive()) { IsBackground = true }.Start();
}
这是线程:
private ThreadStart Receive()
{
while (true)
{
try
{
byte[] inStream = new byte[1024];
serverStream.Read(inStream, 0, inStream.Length);
string returndata = Encoding.ASCII.GetString(inStream);
returndata = returndata.Substring(0, returndata.IndexOf("$"));
Msg($"{returndata}");
}
catch(Exception e)
{
MessageBox.Show($"{e.Message}\n\n{e.ToString()}");
}
}
}
请注意,线程应该无限期地运行这个while循环,但是在后台。现在它不会创建新线程并在 MainThread 上运行。问题是我不知道如何在不让客户端陷入这个while循环的情况下启动这个线程。而不是过渡。
解决方案
看来你不明白什么是ThreadStart
. 这是被接受以创建线程的方法的签名。
你打电话时:
new Thread(Receive())
您实际上是在主线程中调用“接收”方法,并将其返回值提供给线程构造函数(这永远不会发生,因为它卡在您的无限循环中。
相反,你需要做
new Thread(new ThreadStart(Receive))
注意删除的括号。
但是你会得到一个编译错误,因为你的 Receive 方法没有正确的签名。所以你需要把它改成:
private void Receive()
{
// ...
}
推荐阅读
- amazon-web-services - 如何从 AWS CDK for python 中的 Bucket 对象获取存储桶名称
- javascript - 我有一个对象列表。我想在第一行显示 8 个项目。如果列表长度超过 8 则添加一个显示更多按钮
- ignite - 从 2.7.0 升级到 2.9.0 后,Ignite 客户端不稳定
- javascript - 这是否遵循策略设计模式
- ios - 提交苹果商店以供审核 info.plist 中的 DarkMode UIUserInterfaceStyle 键
- primefaces - 单击数据表时出现黑色边框
- node.js - 本地 Node.js 包中的 CLI 实用程序
- apache-kafka - 实时处理:Storm/flink vs 标准应用(java、c#...)
- amazon-web-services - Secrets Manager - 在另一个账户中使用 lambda 轮换密钥
- azure - Kusto/Azure 数据资源管理器 - 如何使用时间跨度字段对外部表进行分区?