2011-01-27 13 views
3

私はこのFtpClientライブラリを使用してWinFormsアプリケーションからメインフレームに接続しています。スレッドが読み込みを開始する前にスレッドが応答を待つために、スレッドを使用しています。それ以外の場合は、スレッドがフリーズします。これに代わる方法はありますか?ソケット読み込みの前にThread.Sleep()の代わりに

public void Login() 
{ 
    if (this.loggedin) this.Close(); 

    Debug.WriteLine("Opening connection to " + this.server, "FtpClient"); 

    IPAddress addr = null; 
    IPEndPoint ep = null; 

    try 
    { 
     this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     addr = Dns.Resolve(this.server).AddressList[0]; 
     ep = new IPEndPoint(addr, this.port); 
     this.clientSocket.Connect(ep); 
    } 
    catch (Exception ex) 
    { 
     // doubtfull 
     if (this.clientSocket != null && this.clientSocket.Connected) this.clientSocket.Close(); 

     throw new FtpException("Couldn't connect to remote server", ex); 
    } 

    **Thread.Sleep(4000);** 
    this.readResponse(); 
    ... 
} 

private void readResponse() 
{ 
    this.message = ""; 
    this.result = this.readLine(); 

    if (this.result.Length > 3) 
     this.resultCode = int.Parse(this.result.Substring(0, 3)); 
    else 
     this.result = null; 
} 

private string readLine() 
{ 
    while (true) 
    { 
     this.bytes = clientSocket.Receive(this.buffer, this.buffer.Length, 0); 
     this.message += ASCII.GetString(this.buffer, 0, this.bytes); 

     if (this.bytes < this.buffer.Length) break; 
    } 

    string[] msg = this.message.Split('\n'); 
    if (this.message.Length > 2) 
    { 
     this.message = msg[msg.Length - 2]; 
     try { response = msg[msg.Length - 3]; } 
     catch { } 
    } 
    else 
    { 
     this.message = msg[0]; 
    } 

    if (this.message.Length > 4 && !this.message.Substring(3, 1).Equals(" ")) return this.readLine(); 

    if (this.verboseDebugging) 
    { 
     for (int i = 0; i < msg.Length - 1; i++) 
     { 
      Debug.Write(msg[i], "FtpClient"); 
     } 
    } 
    return message; 
} 

public void sendCommand(String command) 
{ 
    if (this.verboseDebugging) Debug.WriteLine(command, "FtpClient"); 

    Byte[] cmdBytes = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray()); 
    clientSocket.Send(cmdBytes, cmdBytes.Length, 0); 
    this.readResponse(); 
} 

答えて

4

使用非同期プログラミングモデル:Thread.Sleep()を書く

socket.BeginConnect(ep, new AsyncCallback(Connected), socket); 

void Connected (IAsyncResult result) 
{ 
    var socket = (Socket)result.AsyncState; 

    // do the stuff 

    socket.EndConnect(result); 
} 
+0

他のコマンド(アップロード/ダウンロード)を送信している間にログインしていますが、このエラーが発生しました。「以前の非同期呼び出しが進行中にこのソケットで呼び出しをブロックできません。 – user558138

+0

@ user558138:申し訳ありませんが、あなたは 'EndConnect()'を呼び出す必要があると言いました。 – abatishchev

+0

私はまだ同じエラーが発生しています。 clientSocket.Send(cmdBytes、cmdBytes.Length、0); //この行にある – user558138

0

は確かに悪い習慣です。あなたが実際にFTPクライアントを実行している場合

FtpWebRequestBeginGetResponse(asynccallback, object)

を使用して、コールバックとしてreadResonseを渡します。これは、応答が準備されているときに正確に呼び出されます。

+0

悪い練習ですか?私はそうは思わない。しかし、はい、働くことができる他のアプローチがあります。 – stefan

+0

さて、それは悪いデザインの証拠だとしましょう、私はその記事に同意しないでください。http://stackoverflow.com/questions/1457282/alternatives-to-thread-sleep-for-simulating-pauses – rds

+0

あなたがなぜthread.sleep()を使うのかについての推測です。スレッドをスリープ状態にすることは、私の本の中に「何もしてはいけない、何かを処理してから、もう一度やり直してください」と言ってもいい方法です。まだ。まともな睡眠の私の考えは<100ミリ秒で、秒または分ではありません。 – stefan

関連する問題