Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从无名称线程附加textbox?_C#_Multithreading - Fatal编程技术网

C# 如何从无名称线程附加textbox?

C# 如何从无名称线程附加textbox?,c#,multithreading,C#,Multithreading,我正在构建一个简单的服务器,只是想知道如何从处理服务器的线程更新主线程中的文本框 它的for和eventlog要替换MessageBox.Show(“服务器已启动”);具有Form1.EventLog(“服务器已启动”)等功能;这将附加名为*tb_EventLog*的文本框 我在谷歌上搜索了一下,找到了delegate\Invoke要做的事情,也许可以尝试使用BackgroundWorker。但是玩了一整天,所有的尝试都失败了,导致我编译错误,所以重新开始 如果有人能把函数放在那里,并对其进行评

我正在构建一个简单的服务器,只是想知道如何从处理服务器的线程更新主线程中的文本框

它的for和eventlog要替换MessageBox.Show(“服务器已启动”);具有Form1.EventLog(“服务器已启动”)等功能;这将附加名为*tb_EventLog*的文本框

我在谷歌上搜索了一下,找到了delegate\Invoke要做的事情,也许可以尝试使用BackgroundWorker。但是玩了一整天,所有的尝试都失败了,导致我编译错误,所以重新开始

如果有人能把函数放在那里,并对其进行评论,以便我理解它,我将非常感谢

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace test
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
Server.cs

using System;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Windows.Forms;

namespace test
{
    class Server
    {
        private TcpListener tcpListener;
        private Thread listenThread;
        private static bool listen;

        public Server()
        {
          this.tcpListener = new TcpListener(IPAddress.Any, 3000);
          this.listenThread = new Thread(new ThreadStart(ListenForClients));
        }

        public void Start()
        {
            listen = true;
            this.listenThread.Start();
            MessageBox.Show("Server Started");
        }

        public static void Stop()
        {
            listen = false;       
            MessageBox.Show("Server Stopped");
        }

        private void ListenForClients()
        {
            this.tcpListener.Start();

            while (listen)
            {
                //blocks until a client has connected to the server
                TcpClient client = this.tcpListener.AcceptTcpClient();

                //create a thread to handle communication
                //with connected client
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(client);
            }

            this.tcpListener.Stop();
        }

        private void HandleClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;
            NetworkStream clientStream = tcpClient.GetStream();

            byte[] message = new byte[4096];
            int bytesRead;

            while (listen)
            {
                bytesRead = 0;

                try
                {
                    //blocks until a client sends a message
                    bytesRead = clientStream.Read(message, 0, 4096);
                }
                catch
                {
                    //a socket error has occured
                    break;
                }

                if (bytesRead == 0)
                {
                    //the client has disconnected from the server
                    break;
                }



                //message has successfully been received
                ASCIIEncoding encoder = new ASCIIEncoding();
                //System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
                MessageBox.Show(encoder.GetString(message, 0, bytesRead));

                byte[] buffer = encoder.GetBytes("HTTP/1.1 200 OK\r\n\r\nHello World!");

                clientStream.Write(buffer, 0, buffer.Length);
                clientStream.Flush();
                clientStream.Close();
            }

            tcpClient.Close();
        }
    }

  }
还有,停止服务器线程的最佳方法是什么,我做得对吗

非常感谢

已更新

好的,我已经编辑了上面的代码并删除了oThread,因为它毫无意义

请帮我解决这个问题听起来很简单,但它让我发疯:)我试图让服务器类在主线程上更新一个文本框

再次感谢。

您应该使用事件:

class Server
{
   public event EventHandler ServerStarted;

   protected virtual void OnServerStarted()
   {
       var handler = this.ServerStarted;
       if(handler != null)
       {
           handler(this,EventArgs.Empty);
       }
   }

   public void Start()
   {
        listen = true;
        this.listenThread.Start();
        OnServerStarted();
   }
}
然后,在winforms中:

    Server server = new Server();
    server.ServerStarted+= (o,ev) => this.Invoke(new Action( () => this.textBox1.Text = "Server Started"));
    oThread = new Thread(new ThreadStart(server.Start));
    oThread.Start();

要在背景线程上设置文本,请按照BFree的说明执行。关于你的代码,我建议如下-

  • 我认为,您的线程-
    oThread=newthread(newthreadstart(server.Start))是多余的。在
    Server.Start
    中,再次启动侦听器线程。因此,您只需从Winform中调用
    Server.Start

  • 您没有将线程作为后台线程启动。如果某个线程是前台线程,那么只要该线程处于活动状态,应用程序就会一直运行。请参阅此链接-。在程序创建的所有线程实例上,应将
    IsBackground
    属性设置为
    true

  • 为了获得更好的性能,可以使用.NET4或.NET4中的线程。默认情况下,线程将是后台线程。此外,您的程序将不会有线程创建的开销。使用PFX将有助于利用您的多核处理器,提供巨大的性能优势


  • 阅读这本关于线程的优秀指南

    @詹姆斯:不,我说得对。由于start将在另一个线程上调用,因此事件将在该线程(而不是UI线程)上引发,因此您需要在事件处理程序中使用invoke。没错,我的大脑很疲惫,我在想,如果线程在窗体本身上运行一个方法,我将如何处理它,不是来自外部的class@James不管怎样,谢谢你的努力。有人有任何想法或链接吗?@BFree:我现在正在阅读事件处理程序,但我是c#新手,所以不知道从哪里开始:/@BFree:谢谢你的示例,但我需要在服务器类中附加文本框,而不是在运行Form1的主线程中。人们是如何制作他们的事件日志窗口的:)谢谢,我将对此进行研究一个旁注:让Other在窗体上读取一个静态变量似乎是一个非常糟糕的主意。。。您并不想在这个formBFree的每个实例上共享这个线程,它已经为您解决了这个问题,并且包含了示例代码。。。不知道你还想要什么
        Server server = new Server();
        server.ServerStarted+= (o,ev) => this.Invoke(new Action( () => this.textBox1.Text = "Server Started"));
        oThread = new Thread(new ThreadStart(server.Start));
        oThread.Start();