WPF:使用匿名方法的 UnauthorizedAccessException
事情是这样的,我想创建一个简单的应用程序,从一个站点复制许多文件,并将它们移动到另一个站点;但使用异步方法并创建一个新线程。
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); // 这里抛出异常
Here is the thing, I want to create a simply app that copy many files from one site, and move them to another; but using async methods and create a new thread.
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 is throw! It says that I can't access to txtdestino content. Some clues?
-------------------------------------------------------------------------------Edited
This is the version with all the changes, get the same error :( any clues?
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); // here the exception is throw
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对 UI 元素的调用必须在 UI 线程中完成。尝试在循环之前获取文本值。
Calls to UI elements must be done in the UI thread. try getting the text value before your loop.
如果多个线程尝试(同时)访问 txtdestino.Text 处的文件 - 难道这从一开始就注定失败吗?您可能想首先将内容读入内存,然后从那里写入...
同样,您将要对 IO 进行锤击;我想知道是否更实际的答案(解决上面和下面的问题)是简单地按顺序在工作线程上进行复制。
看起来您实际上可能会将此处的所有工作推回 UI 线程无论如何...?当然你应该这样做:
which:
Fi
未捕获)你也有 foreach/capture 问题;将其更改为:
问题是很可能所有线程都试图访问最后文件。不,真的。这是因为
foreach
技术上在循环外部声明了变量(上面的tmp
);变量捕获规则(由 lambdas / anon-methods 使用)表示,因此这是相同变量(重要:lambdas / anon-methods 是完整的词法闭包,并捕获 variable< /em>,而不是值)。在循环内重新声明变量会更改范围,现在 lambda / 匿名方法将变量视为每次循环迭代都不同。
如果您确实想要,我可以将其写成显示所涉及的底层对象的内容,但这取决于您是否需要这种详细程度;p
If multiple threads try to access (simultaneously) the file at
txtdestino.Text
- isn't that doomed from the start? You might want to read the contents into memory first and write from there...Equally, you are going to hammer the IO; I wonder if a more practical answer (that solves the issue above and below) is to simply do the copies sequentially on the worker.
It also looks like you might actually be pushing all the work here back to the UI thread anyway...? surely you should do something like:
which:
Fi
is not captured)You also have the foreach/capture issue; change it to:
The problem is that most likely all the threads are trying to access the last file. No, really. This is because
foreach
technically declares the variable (tmp
above) outside the loop; and the variable capture rules (used by lambdas / anon-methods) say that therefore this is the same variable (important: lambdas / anon-methods are full lexical closures, and capture the variable, not the value).Re-declaring a variable inside the loop changes the scope, and now the lambda / anon-method treats the variable as different per loop iteration.
If you really want, I could write it out in something that shows the underlying objects involved, but it depends whether you want that level of detail ;p
您正在创建多个线程(您找到的每个文件有一个线程)。
问题是只有您的主线程可以访问您的表单元素,否则所有线程都会同时更改您的表单元素。
将 txtdestino.Text 的值传递给您的新线程,您应该没问题。
You are creating multiple threads(1 for each file you find).
The problem is that only your main thread can access your form elements, otherwise all the threads would be changing your form elements at the same time.
Pass the value of txtdestino.Text to your new thread and you should be fine.