簡體   English   中英

WPF:使用匿名方法的UnauthorizedAccessException

[英]WPF: UnauthorizedAccessException using anonymous methods

這就是事情,我想創建一個簡單的應用程序,從一個站點復制許多文件,並將它們移動到另一個站點; 但使用異步方法並創建一個新線程。

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,true); //這里的例外是拋出

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

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

如果多個線程試圖(同時)訪問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 / capture問題(未捕獲Fi
  • 從UI線程讀取路徑並在工作線程上使用它(捕獲)
  • 按順序處理每個文件以避免錘擊IO

你也有foreach / capture問題; 將其更改為:

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

問題是很可能所有線程都試圖訪問最后一個文件。 不完全是。 這是因為foreach 技術上聲明了循環的變量(上面的tmp ); 並且變量捕獲規則(由lambdas / anon-methods使用)表示因此這是相同的變量(重要的是:lambdas / anon-methods是完整的詞法閉包,並且捕獲變量 ,而不是 )。

在循環重新聲明變量會改變范圍,現在lambda / anon-method將變量視為每循環迭代不同。

如果你真的想要,我可以用顯示所涉及的底層對象的東西寫出來,但這取決於你是否想要那個細節級別; p

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM