2013-04-30 80 views
2

我试图用c#上的UI编写服务器程序。 从后台worker->分离线程调用服务器。在服务器'我必须更新关于什么prot的cient连接以及一些其他参数的UI。 据我所知,我必须使用调用,我读了它,但不知何故,我不能在我的代码上实现它。因此,这里是我的代码,感谢提前任何帮助:无法更新服务器线程UI中的文本框

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

您已经提供了*方式*更多的代码来展示问题,并且您没有告诉我们当您尝试发布代码时出了什么问题。请阅读http://tinyurl.com/so-list和http://tinyurl.com/so-hints – 2013-04-30 06:09:06

回答

3

更改UpdateText(string text)这样:

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

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

InvokeMSDN

,直到它 发现具有窗口句柄如果当前 控制的基础窗口句柄还不存在控制或形式invoke方法向上搜索控件的父链。如果找不到合适的句柄 ,则Invoke方法将抛出 异常。在通话期间引发的例外情况将为 传播回主叫方。

+0

我该如何调用服务器线程的调用? – Alexander 2013-04-30 07:22:51

+0

是的。 'Invoke'将找到UI线程,并用它来更新文本框。请参阅编辑。 – 2013-04-30 07:26:22

+0

@Alexander是否有效? – 2013-04-30 11:48:41

0

你应该去“MethodInvoker”跨线程[此外,为确保“办法”执行的GUI线程]

也许这可以帮助:

MethodInvoker method = delegate{ 
     yourTextBox.Text = "the text you need"; 
    }; 
if (InvokeRequired) // You may skip this 
    BeginInvoke(method); 
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