2010-12-09 2 views
0

나는 간단한 서버를 만들고 그냥 서버를 처리하는 스레드에서 주 스레드의 텍스트 상자를 어떻게 업데이트해야하는지 알고 싶었습니다.none-name 스레드에서 textbox를 추가하는 방법은 무엇입니까?

for 및 eventlog를 바꿔야합니다. MessageBox.Show ("Server Started"); 기능이있는Form1.EventLog ("Server Started"); * tb_EventLog *라는 텍스트 상자를 추가합니다.

나는 그것을 봤는데 delegate \ Invoke와 함께 할 일이있어 아마도 BackgroundWorker를 사용해보십시오. 그러나 하루 종일 놀고 모든 attemps가 실패했고 나를 그렇게 컴파일 된 오류를 일으켰습니다.

누군가가 거기에 기능을 넣고 댓글을 달 수 있다면 이해할 수있어서 매우 감사 할 것입니다.

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

    } 

가, 내가했던

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 그것은 정확하게?

많은 감사 나는 위의 코드를 편집하고 무의미로 sugguested 된 것처럼 oThread을 제거한

확인 업데이트]

.

제발이 소리를 간단하게 해결하도록 도와주세요.하지만 저를 미치게합니다. :) 서버 클래스를 메인 스레드에서 텍스트 상자를 업데이트하려고합니다.

Thanks again.

+0

보조 노트를 스레딩에이 훌륭한 가이드를 읽어 이 양식의 인스턴스 –

+0

BFree가이 문제를 해결했으며 샘플 코드를 포함하고 있습니다. 더 원하는 것이 무엇인지 확실하지 않습니다. –

답변

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

, 윈폼 당신의 : BFree 설명 것처럼

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

@James : 아니, 맞습니다. start는 다른 스레드에서 호출되므로 UI ​​스레드가 아닌 해당 스레드에서 이벤트가 발생하므로 이벤트 처리기에서 invoke를 사용해야합니다. – BFree

+0

맞아, 내 두뇌가 피곤하고, 스레드가 외부 클래스가 아닌 폼 자체에서 메소드를 실행하고 있다면 어떻게 처리 할까 생각하고있다. –

+0

@James B : 어쨌든 시도해 주셔서 감사합니다. 누구나 아이디어 나 링크가 있습니까? – allycat

0

백그라운드 스레드에서 텍스트의 설정 방법은 않습니다. 코드에 대해 나는 다음과 같은 제안 - 내가 생각

  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. 더 나은 성능을 얻으려면 닷넷 4의 ThreadPool 또는 PFX Tasks의 스레드를 사용하십시오.스레드는 기본적으로 백그라운드 스레드가됩니다. 게다가 당신의 프로그램은 스레드 생성의 오버 헤드를 가지지 않을 것입니다. PFX를 사용하면 멀티 코어 프로세서를 활용하여 성능을 크게 향상시킬 수 있습니다. ... 당신이 정말로 모든에서이 스레드를 공유하지 않으 양식에 정적 변수를 oThread 만드는 것은 정말 나쁜 생각처럼 보인다

http://www.albahari.com/threading/

+0

감사합니다. – allycat

관련 문제