在 c# 中处理另一个 class 的按钮逻辑问题
Problem with a button logic to work on another class in c#
在我的程序中我现在有 2 个 classes 它最终会随着更多的 classes 而增长,第一个 class 是我的主要 class windows 表单,其中包含所有按钮和文本等。现在在我的主表单中,我有一个名为关闭连接的按钮,单击该按钮时,循环将从第二个 class 结束。我遇到的问题是如何完成能够从我的主 class.
按钮关闭该循环
这是主要的class代码
using System;
using System.Windows.Forms;
namespace BarcodeReceivingApp
{
//TelnetConnection stopConnection = new TelnetConnection();
public partial class BarcodeReceivingForm : Form
{
//GLOBAL VARIABLES
private const string Hostname = "myip";
private const int Port = 23;
public BarcodeReceivingForm()
{
InitializeComponent();
//FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
}
private void btn_ConnectT_Click(object sender, EventArgs e)
{
var readData = new TelnetConnection(Hostname, Port);
readData.ServerSocket(Hostname, Port, this);
}
private void btn_StopConnection_Click(object sender, EventArgs e)
{
var connection = new TelnetConnection(Hostname, Port);
connection.CloseConnection();
}
private void btn_RemoveItemFromListAt_Click(object sender, EventArgs e)
{
for (var i = lst_BarcodeScan.SelectedIndices.Count - 1; i >= 0; i--)
{
lst_BarcodeScan.Items.RemoveAt(lst_BarcodeScan.SelectedIndices[i]);
}
}
private void BarcodeReceivingForm_Load(object sender, EventArgs e)
{
lst_BarcodeScan.SelectionMode = SelectionMode.MultiSimple;
}
private void btn_ApplicationSettings_Click(object sender, EventArgs e)
{
var bcSettingsForm = new BarcodeReceivingSettingsForm();
bcSettingsForm.Show();
}
}
}
第二个 class 代码,其中大部分逻辑是
在 ReadWrite() 方法中,我需要在 stopconnection 中放置例如 button.click 然后中断循环并关闭端口 23 连接,这部分我在关闭连接方法中完成了我在之后调用while 循环。现在写我有命令变量=退出然后打破循环但我不想成为我想要按钮这样做的原因
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.Remoting.Messaging;
using System.Security.Authentication.ExtendedProtection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BarcodeReceivingApp
{
public class TelnetConnection
{
private Thread _readWriteThread;
private TcpClient _client;
private NetworkStream _networkStream;
private string _hostname;
private int _port;
private BarcodeReceivingForm _form;
public TelnetConnection(string hostname, int port)
{
this._hostname = hostname;
this._port = port;
}
public TelnetConnection()
{
}
public void ServerSocket(string ip, int port, BarcodeReceivingForm f)
{
this._form = f;
try
{
_client = new TcpClient(ip, port);
}
catch (SocketException)
{
MessageBox.Show(@"Failed to connect to server");
return;
}
_networkStream = _client.GetStream();
_readWriteThread = new Thread(ReadWrite);
//_readWriteThread = new Thread(() => ReadWrite(f));
_readWriteThread.Start();
}
public void ReadWrite()
{
while (true)
{
var command = "";
if (command == "Exit")
break;
var received = Read();
if (_form.lst_BarcodeScan.InvokeRequired)
{
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate { _form.lst_BarcodeScan.Items.Add(received + Environment.NewLine); }));
}
}
CloseConnection();
}
public string BarcodeRead()
{
var reading = Read();
return reading;
}
public string Read()
{
var data = new byte[1024];
var received = "";
var size = _networkStream.Read(data, 0, data.Length);
received = Encoding.ASCII.GetString(data, 0, size);
return received;
}
public void CloseConnection()
{
Console.WriteLine(@"Closed Connection");
_networkStream.Close();
_client.Close();
}
}
}
此外,我一直在 google 上搜索,也在 stack overflow 上搜索类似问题的内容,但我找不到任何可以解决我的问题的内容。
您应该将循环更改为在布尔条件更改时自动停止。您可以在这里做一个小改动。您将需要创建一个新方法来调用关闭并稍微更改 ReadWrite
方法
private bool isExiting = false;
public void Exit()
{
isExiting = true;
}
public void ReadWrite()
{
do
{
var received = Read();
if (_form.lst_BarcodeScan.InvokeRequired)
{
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate { _form.lst_BarcodeScan.Items.Add(received + Environment.NewLine); }));
}
} while (!isExiting)
CloseConnection();
}
现在调用 connection.Exit();
将关闭所有内容但是您仍然有问题。您没有在连接表单中保留 class 的实例。在表单中,您需要更改连接和关闭以使用相同的对象。这是两种方法的小改动
private TelnetConnection connection;
private void btn_ConnectT_Click(object sender, EventArgs e)
{
connection = new TelnetConnection(Hostname, Port);
connection.ServerSocket(Hostname, Port, this);
}
private void btn_StopConnection_Click(object sender, EventArgs e)
{
connection.Exit();
}
现在他们都使用同一个对象,所以它应该可以正常工作。
NetworkStream.Read() returns 0 当套接字关闭时,您可以使用它来跳出循环。所以 return 当读取 returns 0.
时为 null
public string Read()
{
var data = new byte[1024];
var received = "";
var size = _networkStream.Read(data, 0, data.Length);
if(size == 0)
return null;
received = Encoding.ASCII.GetString(data, 0, size);
return received;
}
并在您的 ReadWrite 方法中
public void ReadWrite()
{
while (true)
{
var command = "";
if (command == "Exit")
break;
var received = Read();
if(received == null)
break;
if (_form.lst_BarcodeScan.InvokeRequired)
{
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate { _form.lst_BarcodeScan.Items.Add(received + Environment.NewLine); }));
}
}
CloseConnection();
}
在我的程序中我现在有 2 个 classes 它最终会随着更多的 classes 而增长,第一个 class 是我的主要 class windows 表单,其中包含所有按钮和文本等。现在在我的主表单中,我有一个名为关闭连接的按钮,单击该按钮时,循环将从第二个 class 结束。我遇到的问题是如何完成能够从我的主 class.
按钮关闭该循环这是主要的class代码
using System;
using System.Windows.Forms;
namespace BarcodeReceivingApp
{
//TelnetConnection stopConnection = new TelnetConnection();
public partial class BarcodeReceivingForm : Form
{
//GLOBAL VARIABLES
private const string Hostname = "myip";
private const int Port = 23;
public BarcodeReceivingForm()
{
InitializeComponent();
//FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
}
private void btn_ConnectT_Click(object sender, EventArgs e)
{
var readData = new TelnetConnection(Hostname, Port);
readData.ServerSocket(Hostname, Port, this);
}
private void btn_StopConnection_Click(object sender, EventArgs e)
{
var connection = new TelnetConnection(Hostname, Port);
connection.CloseConnection();
}
private void btn_RemoveItemFromListAt_Click(object sender, EventArgs e)
{
for (var i = lst_BarcodeScan.SelectedIndices.Count - 1; i >= 0; i--)
{
lst_BarcodeScan.Items.RemoveAt(lst_BarcodeScan.SelectedIndices[i]);
}
}
private void BarcodeReceivingForm_Load(object sender, EventArgs e)
{
lst_BarcodeScan.SelectionMode = SelectionMode.MultiSimple;
}
private void btn_ApplicationSettings_Click(object sender, EventArgs e)
{
var bcSettingsForm = new BarcodeReceivingSettingsForm();
bcSettingsForm.Show();
}
}
}
第二个 class 代码,其中大部分逻辑是 在 ReadWrite() 方法中,我需要在 stopconnection 中放置例如 button.click 然后中断循环并关闭端口 23 连接,这部分我在关闭连接方法中完成了我在之后调用while 循环。现在写我有命令变量=退出然后打破循环但我不想成为我想要按钮这样做的原因
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.Remoting.Messaging;
using System.Security.Authentication.ExtendedProtection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BarcodeReceivingApp
{
public class TelnetConnection
{
private Thread _readWriteThread;
private TcpClient _client;
private NetworkStream _networkStream;
private string _hostname;
private int _port;
private BarcodeReceivingForm _form;
public TelnetConnection(string hostname, int port)
{
this._hostname = hostname;
this._port = port;
}
public TelnetConnection()
{
}
public void ServerSocket(string ip, int port, BarcodeReceivingForm f)
{
this._form = f;
try
{
_client = new TcpClient(ip, port);
}
catch (SocketException)
{
MessageBox.Show(@"Failed to connect to server");
return;
}
_networkStream = _client.GetStream();
_readWriteThread = new Thread(ReadWrite);
//_readWriteThread = new Thread(() => ReadWrite(f));
_readWriteThread.Start();
}
public void ReadWrite()
{
while (true)
{
var command = "";
if (command == "Exit")
break;
var received = Read();
if (_form.lst_BarcodeScan.InvokeRequired)
{
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate { _form.lst_BarcodeScan.Items.Add(received + Environment.NewLine); }));
}
}
CloseConnection();
}
public string BarcodeRead()
{
var reading = Read();
return reading;
}
public string Read()
{
var data = new byte[1024];
var received = "";
var size = _networkStream.Read(data, 0, data.Length);
received = Encoding.ASCII.GetString(data, 0, size);
return received;
}
public void CloseConnection()
{
Console.WriteLine(@"Closed Connection");
_networkStream.Close();
_client.Close();
}
}
}
此外,我一直在 google 上搜索,也在 stack overflow 上搜索类似问题的内容,但我找不到任何可以解决我的问题的内容。
您应该将循环更改为在布尔条件更改时自动停止。您可以在这里做一个小改动。您将需要创建一个新方法来调用关闭并稍微更改 ReadWrite
方法
private bool isExiting = false;
public void Exit()
{
isExiting = true;
}
public void ReadWrite()
{
do
{
var received = Read();
if (_form.lst_BarcodeScan.InvokeRequired)
{
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate { _form.lst_BarcodeScan.Items.Add(received + Environment.NewLine); }));
}
} while (!isExiting)
CloseConnection();
}
现在调用 connection.Exit();
将关闭所有内容但是您仍然有问题。您没有在连接表单中保留 class 的实例。在表单中,您需要更改连接和关闭以使用相同的对象。这是两种方法的小改动
private TelnetConnection connection;
private void btn_ConnectT_Click(object sender, EventArgs e)
{
connection = new TelnetConnection(Hostname, Port);
connection.ServerSocket(Hostname, Port, this);
}
private void btn_StopConnection_Click(object sender, EventArgs e)
{
connection.Exit();
}
现在他们都使用同一个对象,所以它应该可以正常工作。
NetworkStream.Read() returns 0 当套接字关闭时,您可以使用它来跳出循环。所以 return 当读取 returns 0.
时为 nullpublic string Read()
{
var data = new byte[1024];
var received = "";
var size = _networkStream.Read(data, 0, data.Length);
if(size == 0)
return null;
received = Encoding.ASCII.GetString(data, 0, size);
return received;
}
并在您的 ReadWrite 方法中
public void ReadWrite()
{
while (true)
{
var command = "";
if (command == "Exit")
break;
var received = Read();
if(received == null)
break;
if (_form.lst_BarcodeScan.InvokeRequired)
{
_form.lst_BarcodeScan.Invoke(new MethodInvoker(delegate { _form.lst_BarcodeScan.Items.Add(received + Environment.NewLine); }));
}
}
CloseConnection();
}