WPF:使用匿名方法未授权的accessexception
-
09-10-2019 - |
题
这是事情,我想创建一个简单的应用程序,将许多文件从一个站点复制,然后将其移至另一个站点;但是使用异步方法并创建一个新线程。
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的值传递到您的新线程,您应该没问题。