2011-01-11 96 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

在代碼中的位置是拋出Exception? – 2011-01-11 18:13:31

回答

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以上)外部循環;和可變捕獲規則(由lambda表達式/匿名的方法中使用)說因此這是相同變量(重要:lambda表達式/匿名的方法是充分詞法關閉,並捕獲可變,而不是) 。

重新聲明變量內部循環會改變的範圍,並且現在拉姆達/匿名-方法治療的變量作爲每循環迭代不同。

如果你真的想,我可以寫出來的東西,顯示的基礎對象參與其中,但是這取決於你是否要詳細程度,P

+0

已編輯!我希望你能幫助我,這讓我瘋狂。 – 2011-01-11 08:41:59

+0

@Diego - 愚蠢的問題,但*用戶是否有權寫入目標位置*?並從源頭上讀取? – 2011-01-11 09:15:23

+0

當然,我們正在談論我的電腦的桌面!一些建議? – 2011-01-11 18:52:01

1

您正在創建多個線程(各1個文件你找到)。
問題是隻有你的主線程可以訪問你的表單元素,否則所有的線程都會同時改變你的表單元素。

將txtdestino.Text的值傳遞給你的新線程,你應該沒問題。

2

對UI元素的調用必須在UI線程中完成。嘗試在循環之前獲取文本值。

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