如果客户端在服务器失去焦点时连接到它(例如屏幕保护程序正在运行),C# 服务器将关闭/崩溃

标签 c# .net winforms visual-studio-2010

我正在使用 TCP 套接字编写客户端-服务器应用程序。服务器是使用 Visual Studio 2010 (.NET 4.0) 用 C# 编写的。服务器同时允许多个客户端连接,因此我使用的是异步。风格。服务器需要连接到数据库 (MySQL),当服务器程序运行时我需要与数据库交互。出于这个原因,我使用 BackgroundWorker 来运行无限监听循环(将接受客户端),以防止界面卡住并能够从可视界面访问数据库。

除非服务器程序失去焦点,否则一切正常。失去焦点的例子是:运行服务器程序的 PC 启动屏幕保护程序,您单击任务栏上的时钟以查看时间,您打开另一个窗口(Windows 资源管理器、计算器...)。如果服务器程序失去焦点并且客户端尝试连接,则服务器将完全关闭!如果我从 Visual Studio 运行服务器,它不会抛出任何错误或异常。如果我运行的是服务器的发布版本,Microsoft Windows 将显示“编程未响应...”对话框。

这是我的代码的结构:

主类中的变量:

const int portNo  = 12345;
static System.Net.IPAddress localAdd = System.Net.IPAddress.Parse("192.168.1.67");
static TcpListener tcpListenerReadWrite  = new TcpListener(localAdd, portNo);

在主窗体中,一个按钮启动服务器:

private void button1_Click(object sender, EventArgs e)
{
    tcpListenerReadWrite.Start();
    backgroundWorker1.RunWorkerAsync();
}

后台 worker DoWork函数:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    while (true)
    {
        ChatClient clientRead = new ChatClient(tcpListenerReadWrite.AcceptTcpClient());
    }
}

在Server类中,构造函数如下:

public ChatClient(TcpClient client) //constructor
{
    _client = client;
    _clientIP = client.Client.RemoteEndPoint.ToString();

    //start reading data from the client in a separate thread
    data = new byte[_client.ReceiveBufferSize];
    _client.GetStream().BeginRead(data, 0, Convert.ToInt32(_client.ReceiveBufferSize), ReceiveMessage, client);
}

当服务器收到消息时:

public void ReceiveMessage(IAsyncResult asyncResult)
{
    //read received message from client
}

最后两个注意事项:(1) 当客户端连接到服务器时,它做的第一件事就是向服务器发送消息,例如 Hello 消息,(2) 在将服务器写入可视化界面之前,我正在测试它一个控制台模式,这个问题不存在,屏幕保护程序曾经运行但没有任何反应。当然在控制台模式下我没有使用任何 BackgroundWorker。

知道服务器崩溃的原因吗?

最佳答案

它与在主 UI 线程而不是后台线程上创建的 TcpListener 有什么关系吗?您自己说过这不会发生在控制台应用程序中。我怀疑由于您现在涉及一些 UI 元素,所以它不是那么清晰。

我的建议是将网络的所有 移动到用户界面线程之外,而不是在“主”类中。让它完全独立。

关于如果客户端在服务器失去焦点时连接到它(例如屏幕保护程序正在运行),C# 服务器将关闭/崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8378215/

相关文章:

c# - 具有相同名称的多个单选按钮需要架构

c# - DrawItem 事件中某个 listView 项的 State 错误

c# - ThreadStart with Parameter 方法

来自列表/字典/数据表的 C# datagridview 组合框列数据源

c# - Microsoft Visual Studio 表单应用程序 - mysql 错误

c# - 如何比较两个通用对象与嵌套集合

c# - 将一个工厂注入(inject)一个类

c# - 使用模板和字段将新页面添加到 iTextSharp 的 PdfStamper

c# - 对跟踪状态的类进行单元测试

.net - 不应该直接调用垃圾收集器的原因