这是事情,我想创建一个简单的应用程序,将许多文件从一个站点复制,然后将其移至另一个站点;但是使用异步方法并创建一个新线程。

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();
    }
}

未经授权的accessexception是抛出的!它说我无法访问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); //这里例外是投掷

有帮助吗?

解决方案

如果多个线程尝试(同时)在 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/捕获问题;将其更改为:

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

问题是很可能 全部 线程正在尝试访问 最后的 文件。不完全是。这是因为 foreach 从技术上讲 声明变量(tmp 以上) 外部 循环;并且可变捕获规则(由lambdas / anon-hethods使用)说,因此这是 相同的 变量(重要:lambdas / anon方法是完整的词汇封闭,并捕获 多变的, ,不是 价值).

重新删除变量 里面 循环更改范围,现在lambda / anon-hethod将变量视为每个循环迭代的不同。

如果你 真的 想要,我可以用显示涉及的基础对象的东西写出来,但这取决于您是否想要该级别的细节; P

其他提示

对UI元素的调用必须在UI线程中完成。在循环之前尝试获取文本值。

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

您正在创建多个线程(每个文件1)。
问题是只有您的主线程才能访问您的表单元素,否则所有线程都会同时更改您的表单元素。

将txtdestino.text的值传递到您的新线程,您应该没问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top