2

我试图在 c# 上编写一个带有 UI 的服务器程序。服务器是从后台工作人员-> 分离线程调用的。在服务器中,我必须更新关于什么 cient 连接到什么 prot 的 UI,以及一些其他参数。我知道我必须使用 Invoke 并且我阅读了它,但不知何故我无法在我的代码上实现它。所以这是我的代码,感谢您的帮助:

enter code here


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Configuration;
using System.Collections;



namespace WindowsFormsApplication1
{


    public partial class ServerAppMainDisplay : Form
    {
        public Int32 local_port = 40000;
        public int StopOrSrart = 0;
        public string localIP = "?";
        public string myHostName = "?";
        public string ServerIP = "Server IP: ";
        public string DefaultPort = "Listening on default port: ";
        public string MachineName = "Machine Name: ";
        public static bool ThrdState = false;
        public static bool TxtBoxVsblty = false; 

        public ServerAppMainDisplay()
        {
            InitializeComponent();
            textBox2.Text = DefaultPort;
            textBox1.Text = ServerIP;
            textBox3.Text = MachineName;
            textUpdate.ShowDialogs();
        }



        private void UpdateText(string text)
        {
            // Set the textbox text
            textBox5.Text = text;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            myHostName = Dns.GetHostName().ToString();
            localIP = Dns.Resolve(myHostName).AddressList[0].ToString();
            textBox1.Text = ServerIP + localIP;
            textBox3.Text = MachineName + myHostName;
            textBox2.Text = DefaultPort + local_port.ToString();
            backgroundWorker1.RunWorkerAsync();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //Data Log txt
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //Data Log Excel
        }

        private void button4_Click(object sender, EventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show("Are you sure you want to stop server application?",
                "Stop server application", MessageBoxButtons.YesNo);
            if (dialogResult == DialogResult.Yes)
            {
                textBox2.Text = DefaultPort;
                textBox1.Text = ServerIP;
                textBox3.Text = MachineName;
                myTCPServer.thread.Abort();
                myTCPServer.listener.Stop();
                myTCPServer.DefSoc.Dispose();
                for (int i = 1; i < 10; i++)
                {
                    if (myTCPServer.Connection[i].portFlag)
                    {
                        myTCPServer.Connection[i].slistener.Stop();
                        myTCPServer.Connection[i].socket.Dispose();
                    }
                }
                ThrdState = true;
                TxtBoxVsblty = false;
            }
            if (dialogResult == DialogResult.No) return;
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            myTCPServer.myMain();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit server window application?",
                "Exit server window application", MessageBoxButtons.YesNo);
            if (dialogResult == DialogResult.Yes)
            {
                backgroundWorker1.Dispose();
                backgroundWorker1.CancelAsync();
                myTCPServer.thread.DisableComObjectEagerCleanup();
                myTCPServer.thread.Abort();
                this.Close();
                Application.Exit();
            }
            if (dialogResult == DialogResult.No) return;
        }

    }
    public class myTCPServer
    {
        public static Socket DefSoc;
        public static Thread thread = new Thread(new ThreadStart(Service));
        public static TcpListener listener;
        public struct Connection_s
        {
            public int port;
            public bool portFlag;
            public Socket socket;
            public TcpListener slistener;
        };
        public static myTCPServer.Connection_s[] Connection = new myTCPServer.Connection_s[10];
        public const int DefaultPort = 40000;

        public static void myMain()
        {
            if (!WindowsFormsApplication1.ServerAppMainDisplay.ThrdState)
                myTCPServer.thread.Start();
            else
            {
                myTCPServer.thread = new Thread(new  ThreadStart(Service));
                myTCPServer.thread.Start();
            }
        }
        public static void Service()
        {

            for (int i = 1; i < 10; i++)
            {
                Connection[i].portFlag = false;
                Connection[i].port = DefaultPort + i;
            }
            myTCPServer.listener = new TcpListener(DefaultPort);
            myTCPServer.DefSoc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            while (true)
            {
                byte[] SndBfr;
                string str;
               myTCPServer.listener.Start();
               if (myTCPServer.listener.Pending())
                {
                    DefSoc = myTCPServer.listener.AcceptSocket();
                for (int i = 1; i < 10; i++)
                {

                    if (Connection[i].portFlag == false)
                    {
                        Thread.Sleep(10);
                        str = "<" + Connection[i].port as string;
                        SndBfr = System.Text.Encoding.UTF8.GetBytes(str);
                        DefSoc.Send(SndBfr);
                        Thread.Sleep(10);
                        Connection[i].slistener = new TcpListener(Connection[i].port);
                        Connection[i].slistener.Start();
                        Connection[i].socket = Connection[i].slistener.AcceptSocket();
                        Connection[i].portFlag = true;
                        yourTextBox.Invoke(new UpdateTextCallback(this.UpdateText), 
                            new object[]{”Text generated on non-UI thread.”});
                        DefSoc.Disconnect(true);
                        DefSoc.Dispose();
                        myTCPServer.listener.Stop();
                        myTCPServer.listener = new TcpListener(DefaultPort);
                        myTCPServer.DefSoc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        break;
                    }
                    }
                }
                Thread.Sleep(10);
                for (int i = 1; i < 10; i++)
                {
                    if (Connection[i].portFlag == true)
                    {
                        int SndRslt = 0;

                        str = DateTime.Now.ToString(@"MM\/dd\/yyyy h\:mm tt");
                        try
                        {
                            SndRslt = Connection[i].socket.Send(System.Text.Encoding.UTF8.GetBytes("+" + str));
                        }
                        catch (SocketException) { }
                        if (SndRslt <= 0)
                        {
                            try
                            {
                                Connection[i].portFlag = false;
                                Connection[i].socket.Disconnect(true);
                                Connection[i].slistener.Stop();
                            }
                            catch (SocketException) { }
                        }
                    }
                }
            }
        }
    }
}
4

3 回答 3

3

将您更改UpdateText(string text)为:

    private void UpdateText(string text)
    {
        if(textBox5.InvokeRequired)
        {
           Action a = () => UpdateText(text);
           Invoke(a);
        }
        else 
          textBox5.Text = text;
    }

如果需要,这将调用文本框。

Invoke来自MSDN

如果当前控件的基础窗口句柄尚不存在,Invoke 方法将向上搜索控件的父链,直到找到具有窗口句柄的控件或窗体。如果找不到合适的句柄,Invoke 方法将抛出异常。调用期间引发的异常将传播回调用者。

于 2013-04-30T06:26:36.827 回答
0

您应该为跨线程选择“MethodInvoker”[此外,确保“方法”在 GUI 线程上执行]

也许这会有所帮助:

MethodInvoker method = delegate{
        yourTextBox.Text = "the text you need";
    };
if (InvokeRequired) // You may skip this
    BeginInvoke(method);
于 2013-04-30T06:15:46.627 回答
0

调用更新 UI 的函数的委托,并在函数中使用 InvokeRequired 检查是否需要调用委托。

例子:

Imports System.Management



  Private watcher As New ManagementEventWatcher
//delegate to udater UI function
  Delegate Sub SetItemCallback(ByVal item As ListViewItem)

  Private item1 As ListViewItem

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Dim query As New WqlEventQuery("Win32_ProcessStartTrace")
    watcher.Query = query
    AddHandler watcher.EventArrived, AddressOf EventWorker
    watcher.Start()

  End Sub

  'This method start when event arrived. It's invoked from another thead. (not UI thread)

  Public Sub EventWorker(ByVal sender As Object, ByVal e As System.Management.EventArrivedEventArgs)

    Try

      Dim mbo As ManagementBaseObject = e.NewEvent

      For Each p As PropertyData In mbo.Properties

        item1 = New ListViewItem(p.Name)

        If p.Value IsNot Nothing Then : item1.SubItems.Add(p.Value.ToString)

        Else : item1.SubItems.Add(String.Empty)

        End If

        'updates de UI

        Me.SetItem(item1)


      Next

    Catch ex As Exception

      Console.WriteLine(ex.Message)

    End Try

  End Sub

  'If InvokeRequired (no UI thread) create the delegate and invoke it else update the UI
  Private Sub SetItem(ByVal itm As ListViewItem)

    If Me.ListView1.InvokeRequired Then

      Dim d As New SetItemCallback(AddressOf SetItem)

      Me.Invoke(d, New Object() {itm})

    Else

      ListView1.Items.Add(itm)

    End If

  End Sub

  Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed

    watcher.Stop()

  End Sub
于 2013-04-30T06:19:43.857 回答