2011-01-11 13 views
1

ここでは、あるサイトから多くのファイルをコピーして別のサイトに移動する単純なアプリケーションを作成したいと思います。非同期メソッドを使用して新しいスレッドを作成します。WPF:匿名メソッドを使用したUnauthorizedAccessException

private void button3_Click(object sender, RoutedEventArgs e) 
{ 

    //progressBar1.Maximum = _FileInfoArray.Count; 

    DispatcherTimer dt1 = new DispatcherTimer(); 
    foreach (FileInfo Fi in _FileInfoArray) 
    { 
     Thread t = new Thread(new ThreadStart(delegate() 
     { 
      DispatcherOperation _dispOp = progressBar1.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(delegate() 
      { 

       File.Copy(txtdestino.Text, Fi.FullName, true); 

       //progressBar1.Value = n; 
       //txtstatus.Content = ("Copiados " + n.ToString() + " archivos"); 
       //Thread.Sleep(100); 
      } 
      )); 
      _dispOp.Completed += new EventHandler(_dispOp_Completed); 
     } 
      )); 
     t.Start(); 
    } 
} 

UnauthorizedAccessExceptionがスローです。私はtxtdestinoのコンテンツにアクセスできないと言います。いくつかの手がかり?

---------------------------------------------- ---------------------------------編集 これはすべての変更が加えられたバージョンですが、同じエラーが発生します:(任意の手掛かり

private void button4_Click(object sender, RoutedEventArgs e) 
{ 
    //First: Build mynames 
    List<string> mynames = new List<string>(); 
    foreach (FileInfo fi in _FileInfoArray) 
    { 
     mynames.Add(fi.FullName); 
    } 



    Thread t = new Thread(new ThreadStart(delegate() 
     { 
      foreach (string fullname in mynames) 
      { 
      DispatcherOperation _dispOp = progressBar1.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(delegate() 
      { 
       string destino = System.IO.Path.Combine(@"C:\", System.IO.Path.GetFileName(fullname)); 
       File.Copy(fullname, destino, true); 
       //Some progressbar changes 
      } 
      )); 
      _dispOp.Completed += new EventHandler(_dispOp_Completed); 
      } 
     } 
       )); 
     t.Start(); 
    } 

File.Copy(txtdestino.Text、Fi.FullName、真の);?複数のスレッドが(同時に)アクセスにファイルをしようとした場合//ここで例外がスロー

+0

ここで、例外がスローされていますか? –

答えて

1

ですtxtdestino.Textで - これは最初から運命づけられていませんか?その内容をメモリ最初にと書いてください。そこから書きます...

同様に、あなたはIOをハンマーします。もっと実用的な答え(それは上記のの問題を解決します)は、単に作業者ののコピーを実行するだけです。

実際にすべての作業をUIスレッドに戻しているようですが、とにかく ...?

string path = txtdestino.Text; 
Thread t = new Thread(new ThreadStart(delegate() { 
    foreach (FileInfo Fi in _FileInfoArray) { 
     File.Copy(path, Fi.FullName, true); 
    } 
})); 
t.Start(); 

  • はforeachの/キャプチャの問題(Fiがキャプチャされていない)回避
  • (キャプチャ)UIスレッドからのパスを読み取り、それを使用していますきっとあなたは次のように何かをする必要があります労働者
  • プロセス打撃

IOを回避するために、各ファイルを順番に

foreach/captureの問題もあります。以下のように変更します。

foreach (FileInfo tmp in _FileInfoArray) 
{ 
    FileInfo Fi = tmp; 
    ... 

問題が最も可能性が高いすべてのスレッドが最後ファイルにアクセスしようとしているということです。いいえ、本当に。これは、foreachという技術的にはの変数(tmp)がの外側にあると宣言しているためです。及び(ラムダ/アノン-方法によって使用される)変数捕捉ルールは、したがって、これは同じ可変であることを言う(重要:ラムダ/アノン-方法が満杯字句クロージャであり、可変なく、キャプチャ) 。

に再宣言すると、ループによってスコープが変更され、ラムダ/アノノンメソッドは変数をループごとに異なるものとして扱います。

あなた本当にがしたい場合は、私が関係する基礎となるオブジェクトを示して何かでそれを書くことができ、それはあなたが細部のそのレベルを望んでいるかどうかによって異なり、P

+0

編集済み!私はあなたが私を助けることができると期待して、それは私を夢中にさせる。 –

+0

@Diego - 愚かな質問ですが、*ユーザーはその目標位置*に書き込む権限を持っていますか?そして源から読む? –

+0

もちろん、私は私のPCのデスクトップについて話している!いくつかの提案? –

1

あなたは(それぞれの1を複数のスレッドを作成していますあなたが見つけたファイル)。
問題は、メインスレッドだけがフォーム要素にアクセスできることです。そうしないと、すべてのスレッドがフォーム要素を同時に変更することになります。

txtdestino.Textの値を新しいスレッドに渡すと、問題なく動作します。

+0

今、いくつかの手がかり? –

2

UI要素への呼び出しは、UIスレッドで行う必要があります。ループの前にテキスト値を取得してみてください。

string txt = txtdestino.Text; 
foreach (FileInfo Fi in _FileInfoArray) 
{ 
    .... 
    File.Copy(txt, Fi.FullName, true); 
+0

今、いくつかの手がかり? –

+0

別のスレッドで実行されるデリゲートのいずれかからuiコールを削除する必要があります。そのコードの中からUIコントロールを参照する必要はありません。したがって、 'Dispatcher.Invoke'(または関連する)呼び出しがラップされていないテキストボックスやプログレスバーなどを参照する必要はありません! –

+0

もうuiコールはありません。ありがとうございました –

関連する問題