这就是问题,我想创建一个简单的应用程序,从一个站点复制许多文件,并将它们移动到另一个站点;但是使用异步方法并创建一个新线程。
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); //这里的例外是抛出
答案 0 :(得分:2)
必须在UI线程中调用UI元素。尝试在循环之前获取文本值。
string txt = txtdestino.Text;
foreach (FileInfo Fi in _FileInfoArray)
{
....
File.Copy(txt, Fi.FullName, true);
答案 1 :(得分: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();
其中:
Fi
)你也有foreach / capture问题;将其更改为:
foreach (FileInfo tmp in _FileInfoArray)
{
FileInfo Fi = tmp;
...
问题是,线程最有可能全部尝试访问最后文件。不完全是。这是因为foreach
技术上声明变量(上面的tmp
)在之外的循环;并且变量捕获规则(由lambdas / anon-methods使用)表示因此这是相同的变量(重要的是:lambdas / anon-methods是完整的词法闭包,并捕获变量< / em>,而不是值)。
在中重新声明变量循环会改变范围,现在lambda / anon-method将变量视为每循环迭代不同。
如果真的想要,我可以用显示所涉及的底层对象的东西写出来,但这取决于你是否想要那么详细的等级; p
答案 2 :(得分:1)
您正在创建多个线程(您找到的每个文件都有1个) 问题是只有主线程可以访问表单元素,否则所有线程都会同时更改表单元素。
将txtdestino.Text的值传递给新线程,你应该没问题。