如何从非名称线程追加文本框?

时间:2010-12-09 04:47:34

标签: c# multithreading

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

它的for和eventlog所以想用一个函数替换 MessageBox.Show(“Server Started”); Form1.EventLog(“Server Started”); 将附加名为* tb_EventLog *的文本框。

我用google搜索了一下,并通过委托\ 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());
        }
    }
}

Form1.cs的

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.Threading;

namespace test
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Botton Pressed");
            Server server = new Server();
            server.Start();

        }

        private void button2_Click(object sender, EventArgs e)
        {
            Server.Stop();

        }
    }
}

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,因为它没有意义。

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

再次感谢。

2 个答案:

答案 0 :(得分:1)

你应该使用事件:

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

答案 1 :(得分:0)

用于在后台线程上设置文本,请按照BFree的说明进行操作。关于你的代码,我建议如下 -

  1. 我认为,您的主题 - oThread = new Thread(new ThreadStart(server.Start));是多余的。在Server.Start中,您将再次启动侦听器线程。因此,您只需从Winform中调用Server.Start

  2. 您没有将线程作为后台线程启动。如果一个线程是一个前台线程,只要线程处于活动状态,它就会让你的应用程序继续运行。请参阅此链接 - http://msdn.microsoft.com/en-us/library/h339syd0.aspx。您应该在程序创建的所有线程实例上将IsBackground属性设置为true

  3. 为了获得更好的性能,请使用.Net 4中ThreadPoolPFX Tasks的线程。默认情况下,线程将是后台线程。此外,您的程序将不会有线程创建的开销。使用PFX将有助于利用您的多核处理器提供卓越的性能优势。

  4. 阅读这篇关于线程http://www.albahari.com/threading/

    的优秀指南