c# - 启动服务器使我的应用程序挂起
问题描述
所以在过去的 4 天里,我用 TCPListener 和 TCPClient 进行了测试。我已经轻松地创建了一个独立的服务器/侦听器和一个独立的发送器/客户端。现在我试图在一个应用程序中完成所有操作,但是当我尝试启动服务器时,整个应用程序都会挂起。我不明白为什么,因为它与我在不同应用程序中的代码几乎相同。
我尝试了它的多种变体并观看了多个教程,但实际上它与我已经使用过的代码相同,我不知道发生了什么。
一旦我单击触发 StartButton_Click 方法的开始按钮,就会出现问题
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace ChatTest2
{
public partial class Form1 : Form
{
private TcpClient client;
public StreamReader STR;
public StreamWriter STW;
public string recieve;
public String TextToSend;
public Form1()
{
InitializeComponent();
IPAddress[] localIP = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress address in localIP)
{
if (address.AddressFamily == AddressFamily.InterNetwork)
{
ServerIPtextBox.Text = address.ToString();
}
}
}
private void StartButton_Click(object sender, EventArgs e)
{
TcpListener listener = new TcpListener(IPAddress.Any, int.Parse(ServerPorttextBox.Text));
listener.Start();
client = listener.AcceptTcpClient();
STR = new StreamReader(client.GetStream());
STW = new StreamWriter(client.GetStream());
STW.AutoFlush = true;
backgroundWorker1.RunWorkerAsync();
backgroundWorker2.WorkerSupportsCancellation = true;
}
private void ConnectButton_Click(object sender, EventArgs e)
{
client = new TcpClient();
IPEndPoint IpEnd = new IPEndPoint(IPAddress.Parse(ClientIPtextBox.Text), int.Parse(ClientPorttextBox.Text));
try
{
client.Connect(IpEnd);
if (client.Connected)
{
ChatScreentextBox.AppendText("Connected to server" + "\n");
STW = new StreamWriter(client.GetStream());
STR = new StreamReader(client.GetStream());
STW.AutoFlush = true;
backgroundWorker1.RunWorkerAsync();
backgroundWorker2.WorkerSupportsCancellation = true;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (client.Connected)
{
try
{
recieve = STR.ReadLine();
this.ChatScreentextBox.Invoke(new MethodInvoker(delegate ()
{
ChatScreentextBox.AppendText("You:" + recieve + "\n");
}));
recieve = "";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
}
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
if (client.Connected)
{
STW.WriteLine(TextToSend);
this.ChatScreentextBox.Invoke(new MethodInvoker(delegate ()
{
ChatScreentextBox.AppendText("Me:" + TextToSend + "\n");
}));
}
else
{
MessageBox.Show("Sending failed");
}
backgroundWorker2.CancelAsync();
}
private void SendButton_Click(object sender, EventArgs e)
{
if (MessagetextBox.Text != "")
{
TextToSend = MessagetextBox.Text;
backgroundWorker2.RunWorkerAsync();
}
MessagetextBox.Text = "";
}
}
}
解决方案
client = listener.AcceptTcpClient();
此行阻塞了您的 UI 线程。
我会尝试使用异步和等待。
private async void StartButton_Click(object sender, EventArgs e)
{
TcpListener listener = new TcpListener(IPAddress.Any, int.Parse(ServerPorttextBox.Text));
listener.Start();
client = await listener.AcceptTcpClientAsync();
STR = new StreamReader(client.GetStream());
STW = new StreamWriter(client.GetStream());
STW.AutoFlush = true;
backgroundWorker1.RunWorkerAsync();
backgroundWorker2.WorkerSupportsCancellation = true;
}
我希望它对你有帮助。
推荐阅读
- mysql - 恢复 MySQL 数据
- java - Spring Data 在条目尚不存在时插入数据
- ios - 无法为多个单词提供单独的颜色
- ios - 如何上传带有 Alamofire 内部参数的图像
- laravel - 如何将数据选项卡分开导出
- typescript - 获取 BootstrapVue 下拉菜单(b-dropdown)以在单击按钮时显示
- wso2 - 以 base64 格式返回的 WSO2 Enterprise Integrator 注册表值
- angular - 我想在日期中设置小时而不更改日期月份和年份
- reactjs - 此代码中是否缺少某些内容?我无法通过 axios 发帖请求发帖
- hybris - hybris 订单管理和履行扩展之间有什么区别?什么时候应该使用哪一个?