繁体   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