1

複数のファイルを共有フォルダー(Aprox 20)にコピーしようとしていますが、各ファイルは異なるスレッドで同時にコピーされます。

このようなコードを使用してファイルをコピーしています

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);    
WindowsIdentity identity = new WindowsIdentity(username, password);
WindowsImpersonationContext context = identity.Impersonate();

try
{
    File.Copy(@"c:\temp\MyFile.txt", @"\\server\folder\Myfile.txt", true);
}
catch
{
    context.Undo();
}

しかし、いくつかのファイルはコピーされず、私が得るエラーは次のとおりです。

「Nosepuedenrealizarmásconexionesaesteequiporemoto en este momento、yaquehaymásdelasquepuedeaceptar」

翻訳は次のようになります

「現在、このリモートコンピュータは受け入れることができる接続が多いため、これ以上接続することはできません。」

ファイルを共有フォルダーにコピーしたり、接続を明示的に閉じたりする別の方法はありますか?

4

6 に答える 6

3

Windows ワークステーションには、同時に受け入れることができるネットワーク接続の数に制限があります。

あなたは出来る:

  • 20 未満の接続を使用する
  • 別のファイル コピー プロトコルを使用します。ただし、ネットワーク ソケット数の制限に達します。
  • そのような制限がないサーバー OS の使用に切り替える
于 2011-02-21T17:42:16.243 に答える
2

同じスレッドでファイルをコピーしてみてください。接続ごとに 1 つのスレッドを使用すると、サーバーが限界に達する可能性があると確信しています。

于 2011-02-21T17:41:26.073 に答える
1

Windows クライアント オペレーティング システムは、受け入れることができる同時接続数に制限があります。これがサーバー システムであっても、Windows ファイル共有では、管理者が共有への接続数を制限することもできます。

おそらくやりたいことは、同時スレッドを数個に制限することです (3 から 5 で実行する必要があります)。すべてのファイル名をキューに入れ、キューが空になるまで、各スレッドが次に処理するファイルを (適切なロックを使用して) デキューします。これは生産者/消費者スキームと呼ばれます。おまけとして、システムがネットワークの衝突やコンテキストの切り替えを心配するために費やす時間が少なくて済むため、20 個すべてを一度に実行するよりも多くのスループットが得られる可能性があります。

于 2011-02-21T17:44:02.637 に答える
0

もう 1 つのオプションは、ネットワーク ドライブを使用することです。存在を確認し、必要に応じてマップします。ドライブをマッピングおよびマッピング解除するためのコードは、次の私の回答にあります。

ドライブがマップされると、コードはスレッドに関係なく同じ接続を使用する必要があります。これは Web サービス呼び出しで使用されます。これは、その性質上、マルチスレッドであり、ピーク時に毎分数百のファイルをコピーする、非常に使用されるサービスです。私はそれがあなたの場合にうまくいくと比較的確信しています。

C# - Web サービスからネットワーク ドライブをマップする

ドライブが既にマップされているかどうかを確認するには、単に呼び出します

if (System.IO.Directory.Exists(<drive letter here>));

編集 - ネットワーク ドライブを接続および切断するためのコードの追加

public static class NetworkDrives
    {
        public static bool  MapDrive(string DriveLetter, string Path, string Username, string Password)
        {

            bool ReturnValue = false;

            if(System.IO.Directory.Exists(DriveLetter + ":\\"))
            {
                DisconnectDrive(DriveLetter);
            }
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.FileName = "net.exe";
            p.StartInfo.Arguments = " use " + DriveLetter + ": " + Path + " " + Password + " /user:" + Username;
            p.Start();
            p.WaitForExit();

            string ErrorMessage = p.StandardError.ReadToEnd();
            string OuputMessage = p.StandardOutput.ReadToEnd();
            if (ErrorMessage.Length > 0)
            {
                throw new Exception("Error:" + ErrorMessage);
            }
            else
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public static bool DisconnectDrive(string DriveLetter)
        {
            bool ReturnValue = false;
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.FileName = "net.exe";
            p.StartInfo.Arguments = " use " + DriveLetter + ": /DELETE";
            p.Start();
            p.WaitForExit();

            string ErrorMessage = p.StandardError.ReadToEnd();
            string OuputMessage = p.StandardOutput.ReadToEnd();
            if (ErrorMessage.Length > 0)
            {
                throw new Exception("Error:" + ErrorMessage);
            }
            else
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }

    }
于 2011-02-21T17:58:51.523 に答える
0

ほとんどの場合、IO 速度がボトルネックになるため、一度に 1 つまたは 2 つのファイルに転送を制限する方がよい場合があります。おそらく、ディスクの読み取りまたはネットワークのスループットのいずれかを固定しています。最善の策は、1 スレッドから始めてパフォーマンスを測定し、転送速度とスレッドのバランスを求めることです。

于 2011-02-21T17:42:01.810 に答える
0

問題は、各スレッドが独自の接続を確立していることです。ターゲット マシンが受け入れることができるより多くのスレッドを実行している場合、この問題が発生します。この制限を超えないようにする方法を見つける必要があります。

これをマルチスレッド化する必要がある理由はありますか? 答えは「はい」だと確信していますが、マルチスレッド化により複数のコピー操作を一度に実行できるようにすることでコピー操作が高速化されると考えている場合は、そうではありません。bamdwidth は非常に多く、ターゲット PC は特定の速度でしか読み書きできないため、複数のスレッドで複数のファイルを書き込もうとすると、実際には各ファイルを個別に遅くすることになります。

ただし、私が正しいと推測し、複数のスレッドを使用する別の理由がある場合は、別の方法を提案させてください。ファイルをローカルに書き込み、まったく別のプロセスでファイルをコピーします。UI スレッドと他のスレッドが作業を行っている間に、ファイルをコピーできる Windows サービスまたはコンソール アプリケーションを用意します。仲介者を追加すると、さらに複雑になる可能性がありますが、この問題を解消する方法を見つけようとするよりは簡単です。

別の方法は、スレッドを追跡する必要があり、スレッドの数がターゲットマシンで利用可能な接続の数を決して超えないようにすることです。また、マシンに接続している他のプロセスについて心配する必要があるため、実際にはカウントできませんこのアプローチでも。

スレッドを追跡し、適切にロックすることは確かに実行可能ですが、単純にファイルをローカルに書き込み、外部プログラムにファイル転送を実行させることは、書き込みとトラブルシューティングがはるかに簡単です。

于 2011-02-21T17:43:44.417 に答える