2011-01-24 9 views
2

FTPサーバーから多数の小さなファイルをダウンロードする単純なC#アプリケーションを作成しようとしています。FTPダウンロード速度の問題:.NETソケットプログラミングとFtpWebRequest/Responseオブジェクトを使用した場合の比較

Iは、2つのアプローチを試みた:

1 - 一般的なソケットプログラミング

2 - 最初のアプローチを使用した場合たFtpWebRequestとFtpWebResponseを使用して変化する(同じファイルのために)ダウンロード速度

オブジェクト1.5秒から7秒になると、2回目の結果は同じ結果になります。毎回約2.5秒です。

これらの2.5秒のうち約1.4秒がFtpWebRequestオブジェクト(データを受信するためには1.1秒)を開始するプロセスをとることを考慮すると、その差はかなり重要です。

問題は、1番目のアプローチで2番目の方法と同じ安定したダウンロード速度を達成する方法ですか?

第一のアプローチについての問題は、(それはダウンロード時間の約90%を取ると)以下のループに横たわっていたようです:

Int32 intResponseLength = dataSocket.Receive(buffer, intBufferSize, SocketFlags.None);  
while (intResponseLength != 0) 
{ 
    localFile.Write(buffer, 0, intResponseLength); 
    intResponseLength = dataSocket.Receive(buffer, intBufferSize, SocketFlags.None); 
} 

第二のアプローチのためのコードの等価一部は(常に約1.1かかりますs):

Int32 intResponseLength = ftpStream.Read(buffer, 0, intBufferSize); 
while (intResponseLength != 0) 
{ 
    localFile.Write (buffer, 0, intResponseLength); 
    intResponseLength = ftpStream.Read(buffer, 0, intBufferSize); 
} 

私は56bから32kBのバッファを試しましたが、大きな違いはありません。
はまた、オープンデータソケット上のストリームを作成:

Stream str = new NetworkStream(dataSocket); 

とそれを読んで(代わりにdataSocket.Receiveを使用しての)

str.Read(buffer, 0, intBufferSize); 

は...実際にはさらに遅いです助けにはなりません。

ご協力ありがとうございます。

答えて

2

データの可用性をチェックするには、Socket.PollまたはSocket.Selectメソッドを使用する必要があります。何をすれば操作が遅くなるだけでなく、CPUの負荷が大きくなります。 PollまたはSelectは、データが使用可能になるか、またはタイムアウトが経過するまでプロセッサー時間を生成します。同じループを保つことはできますが、上記の方法のいずれかの呼び出しを含み、タイムアウトで再生します(タイムアウトを見つけるのに10ms〜500msの値を試してください)。

+0

明白な 'Thread.Sleep'を使用してビジーループをはるかに少なくするために、過剰なCPU負荷を排除することができます。busy - 少なくともプラットフォーム上の最小スリープ周波数<< 1000Hz)、そしておそらくそれよりもビジーではありません。私は別の方法に反対しているわけではありませんが、注意するべきことです。 –

+0

@pstスリープで転送が遅くなる - バッファにデータがあり、処理を待っている場合、スリープする理由は何ですか? –

+0

ユージーン、 あなたの答えをありがとう。しかし、それは私のために働いていませんでした;-( 以下のように私のコードを修正しました(おそらく少し過度に...?): – user587356

関連する問題