2017-11-29 12 views
-1

問題はForm1にtextbox.Textを設定することです。私はすぐにスレッドセーフであることを知っていました。私はコードに問題が修正されていると思います。私が直面した次の問題は、クライアントのコード化方法がテキストを設定する方法が静的でなければならず、私はそれをどうやって行うのか考えることができないということでした。もちろん、AsyncClientクラス内のクライアントメソッドは静的である必要はありませんが、そうであれば知識が不足しているためです。C#別のクラスとスレッドで静的メソッドからtextbox.Textを変更するにはどうすればいいですか?

私はおそらくあなたが知ることができるように、クライアントのためにMicrosoftからテンプレートを再度使用しています。これは主に私が大学生であり、ちょうど分で学ぶために使っているという事実によるものです。

この質問が既に存在する場合は、事前にお詫びしたいと思いますが、私が見たときに私の問題に十分な具体的なものは見つけられませんでした。

これは、コードの先頭部分からネームスペースを差し引いたものです。私が話した部分に焦点を合わせるためにちょうどそれを分割します。

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    Socket client; 

    public delegate void setTextCallback(string text); 

    public void setText(string text) 
    { 
     if (this.txtLog.InvokeRequired) 
     { 
      // Different thread, use Invoke. 
      setTextCallback d = new setTextCallback(FinishSetText); 
      this.Invoke(d, new object[] { text }); 
     } 
     else 
     { 
      // Same thread, no Invoke. 
      this.txtLog.Text = this.txtLog.Text + text; 

     } 
    } 

    private void FinishSetText(string text) 
    { 
     this.txtLog.Text = this.txtLog.Text + text; 
    } 

上記のコードは、エラーが修正される限り、私が持っていたクロストレッドの問題です。これを行うより良い方法があれば、私は新しいことを試みることになる。コードの下部に上記

// State object for receiving data from remote device. 
    public class StateObject 
    { 
     // Client socket. 
     public Socket workSocket = null; 
     // Size of receive buffer. 
     public const int BufferSize = 256; 
     // Receive buffer. 
     public byte[] buffer = new byte[BufferSize]; 
     // Received data string. 
     public StringBuilder sb = new StringBuilder(); 
    } 

    public class AsyncClient 
    { 
     // The port number for the remote device. 
     private const int port = 8080; 

     // ManualResetEvent instances signal completion. 
     private static ManualResetEvent connectDone = 
      new ManualResetEvent(false); 
     private static ManualResetEvent sendDone = 
      new ManualResetEvent(false); 
     private static ManualResetEvent receiveDone = 
      new ManualResetEvent(false); 

     public struct properties 
     { 
      public static String response { get; set; } 
     } 

     public static Socket StartClient() 
     { 
      IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); 
      // Create a TCP/IP socket. 
      Socket client = new Socket(ipAddress.AddressFamily, 
       SocketType.Stream, ProtocolType.Tcp); 

      // Connect to a remote device. 
      try 
      { 
       // Establish the remote endpoint for the socket. 

       IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); 

       // Connect to the remote endpoint. 
       client.BeginConnect(remoteEP, 
        new AsyncCallback(ConnectCallback), client); 
       connectDone.WaitOne(); 

       // Release the socket. 
       client.Shutdown(SocketShutdown.Both); 
       client.Close(); 

       return client; 
      } 
      catch (Exception e) 
      { 

       setText(e.ToString()); 
       return client; 
      } 
     } 

     private static void ConnectCallback(IAsyncResult ar) 
     { 
      try 
      { 
       // Retrieve the socket from the state object. 
       Socket client = (Socket)ar.AsyncState; 

       // Complete the connection. 
       client.EndConnect(ar); 

       setText(string.Format("Socket connected to {0}", 
        client.RemoteEndPoint.ToString())); 

       // Signal that the connection has been made. 
       connectDone.Set(); 
      } 
      catch (Exception e) 
      { 
       setText(e.ToString()); 
      } 
      //Other AsyncClient methods below. 
     } 

あなたは私がForm1のからメソッドを使用してテキストを設定しようとしています場所を確認することができますが、あなたはまた、メソッドは意味静的で見ることができるように、それは、そのメソッドの静的なバージョンを期待しますThis.textboxを使用する手段がもう機能しない、または少なくともこれが何が起こっているのかを理解していることを意味します。どんな助けでも大歓迎です。

+0

"テキストを設定する方法は静的でなければなりません" - いいえ、確かにそうではありません。 –

+0

私は実際に起こっていたことをその事実として述べていませんでしたが、結局私はここに投稿しました。 – Aelux

+0

その後、 'AsyncClient'のメソッドを' static'ではなくインスタンスメソッドにします。次に、AsyncClientクライアントのインスタンスを構築してから、 'Action setText'をコンストラクタに渡すことができます。 – Enigmativity

答えて

1

staticキーワードを削除し、あなたのAsyncClientクラスの先頭にこのコードを追加します。

public class AsyncClient 
{ 
    private Action<string> setText; 

    public AsyncClient(Action<string> setText) 
    { 
     this.setText = setText; 
    } 

あなたのフォームからインスタンスを作成するときにだけvar ac = new AsyncClient(setText)を行うと、ac.StartClient()を呼び出します。

+0

これは問題を解決したようです:) – Aelux

関連する問題