0

ファイル転送アプリケーション(サーバークライアント)を持っています...ファイルの送信中にキャンセルを有効にしたいです。
クライアントは、backgroundworkerによって機能するSendFileメソッドをキャンセルしてから、受信スレッドをキャンセルするコマンドをサーバーに送信します。
サーバーがこのコマンドを受信すると、Stopメソッドを呼び出しますが、その行でスタックします。network.Read(data、0、data.Length);

どうすればこのスレッドを中止して、network.Read(..)にとらわれることなく 最終的に進むことができますか?
前もって感謝します。

Thread thTransferFile = null;

void Start()
{
    thTransferFile = new Thread(unused => ft.Receive(destPath, Convert.ToInt64(fileSize);
    thTransferFile.Start();
}

void Stop()
{
    thTransferFile.Abort();
}


public void Receive(string destPath, long fileSize)
    {
        using (fs = new FileStream(destPath, FileMode.Create, FileAccess.Write))
        {
            try
            {
                int count = 0;
                long sum = 0;
                data = new byte[packetSize];
                while (sum < fileSize)
                {
                    count = network.Read(data, 0, data.Length);   //thread stucks in this line when i abort it
                    fs.Write(data, 0, count);
                    sum += count;
                }
            }
            finally
            {
                network.Write(new byte[1], 0, 1); //tell client that the file transfer ends
                network.Flush();
                fs.Dispose();
                if (Thread.CurrentThread.ThreadState == ThreadState.AbortRequested)
                {
                    File.Delete(destPath);
                }
            }
      }
4

3 に答える 3

1

NetworkStream.Readは、データを受信するまでブロックされます。NetworkStreamのReadthecommunity ReadTimeoutcommentを使用して、読み取り操作のタイムアウトを設定します。また、Abort()を使用してスレッドを強制終了することを再検討することもできます。whileループにブールフラグを追加し、Stop()が呼び出されたときにそのフラグをfalseに設定します。この停止フラグをaと組み合わせると、ReadTimeoutプログラムが最終的に終了することが保証されます。

中止されるスレッドがcatchブロック、finallyブロック、制約付き実行領域などの保護されたコード領域にある場合、Abortを呼び出すスレッドがブロックする可能性があります。Abortを呼び出すスレッドが、中止されたスレッドが必要とするロックを保持している場合、デッドロックが発生する可能性があります。

于 2012-03-10T07:37:21.253 に答える
1

スレッドを中止する代わりにClose()network。期待どおりに例外がスローされます。

スレッドを強制終了することは大したことではありません。クリーンにしないままにしておくことができるリソースがあるからです...

于 2012-03-10T07:10:14.997 に答える
0

クライアント側からの送信をキャンセルすると解決策が見つかりました.. network.DataAvailable が false に設定されている.. そのため、サーバーの受信メソッドにこの行を追加しました

while ループで:

                while (sum < fileSize)
                {
                    if (network.DataAvailable)
                    {
                        count = network.Read(data, 0, data.Length);
                        fs.Write(data, 0, count);
                        sum += count;
                    }
                }

そのため、ネットワークでスタックすることはありません。もう読んでください。それは完全に機能しました

于 2012-03-10T08:52:52.373 に答える