Проблема с логикой кнопки для работы на другом классе в c # - PullRequest
0 голосов
/ 24 января 2019

В моей программе на данный момент есть 2 класса, которые со временем будут расти с увеличением числа классов. Первый класс - это основной класс формы Windows, в которой у меня есть все мои кнопки, текст и т. Д. Теперь в основной форме у меня естьКнопка называется закрыть соединение, где, когда это нажатие, цикл закончится из второго класса.проблема, которую я имею, состоит в том, как сделать так, чтобы можно было закрыть этот цикл с помощью кнопки моего основного класса.

Вот код основного класса

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();
        }
    }
}

Код второго класса, где большинствологики в методе ReadWrite () мне нужно поместить, например, если button.click из stopconnection, затем разорвать цикл и закрыть соединение через порт 23, которую я сделал, в моем методе соединения close, который я вызываюпосле цикла пока.написать сейчас у меня есть переменная команды = выход, затем прервать цикл, но я не хочу, чтобы именно поэтому я хочу, чтобы кнопка делала это

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, а также напереполнение стека что-то похожее на вопрос, и я не смог найти ничего, что поможет моей проблеме.

Ответы [ 2 ]

0 голосов
/ 24 января 2019

NetworkStream.Read () возвращает 0, когда сокет закрыт, так что вы можете использовать его для выхода из цикла. Так что верните ноль, когда чтение вернет 0.

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();
}
0 голосов
/ 24 января 2019

Вы должны изменить свой цикл, чтобы он автоматически останавливался при изменении логического условия. Здесь небольшое изменение вы можете сделать. Вам нужно будет создать новый метод для вызова закрытия и немного изменить метод 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(); закроет все, но у вас все еще есть проблема. Вы не сохранили экземпляр класса в форме для соединения. В форме необходимо изменить подключение и закрыть, чтобы использовать один и тот же объект. вот небольшие изменения в обоих методах

    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();
    }

Теперь они оба используют один и тот же объект, поэтому он должен работать правильно.

...