[英]C# - Cross-thread operation not valid. Control ListView…and backgroundworker
I have a backgroundworker copying files from a ListView. 我有一个背景工作者从ListView复制文件。 I read many similar questions, but they all seem to be about the DoWork property trying to change a UI control.
我读过许多类似的问题,但它们似乎都与试图更改UI控件的DoWork属性有关。 I'm not changing anything.
我什么都没改变。 I simply go through the file list in the ListView:
我只是浏览ListView中的文件列表:
void BackgroundWorkerDoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
this.timerReminder.Stop();
BackgroundWorker worker = sender as BackgroundWorker;
worker.ReportProgress(0);
string msg = "You are about to copy selected files into selected folder.\n\n" +
"Press Yes to overwrite existing files if they exist in selected folder or\n" +
"Press No to keep files if they exist in selected folder or\n" +
"Press Cancel to cancel back up";
DialogResult dr = MessageBox.Show(msg,
"Start back up",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1);
string dt = string.Format("{0:dd-MM-yyyy-hh-mm-ss}", DateTime.Now);
byte[] buffer = new byte[64 * 1024];
ListView.CheckedListViewItemCollection checkedItems = this.listViewFiles.CheckedItems;
//int count = checkedItems.Count;
switch (dr)
{
case DialogResult.Yes:
foreach (ListViewItem item in checkedItems)
{
string file = item.SubItems[0].Text;
if (File.Exists(file) && worker.CancellationPending == false)
{
using (FileStream source = new FileStream(file, FileMode.Open, FileAccess.Read))
{
long fileLength = source.Length;
string fn = Path.Combine(this.savePath, Path.GetFileName(file));
using (FileStream destination = new FileStream(fn, FileMode.OpenOrCreate, FileAccess.Write))
{
long totalBytes = 0;
int currentBlockSize = 0;
while ((currentBlockSize = source.Read(buffer, 0, buffer.Length)) > 0)
{
totalBytes += currentBlockSize;
destination.Write(buffer, 0, currentBlockSize);
worker.ReportProgress((int)(100.0 * (double)totalBytes / fileLength));
}
}
}
}
else{
e.Cancel = true;
break;
}
}
break;
case DialogResult.No:
foreach (ListViewItem item in checkedItems)
{
string file = item.SubItems[0].Text;
if (File.Exists(file) && worker.CancellationPending == false)
{
using (FileStream source = new FileStream(file, FileMode.Open, FileAccess.Read))
{
long fileLength = source.Length;
string fn = Path.Combine(this.savePath, Path.GetFileNameWithoutExtension(file) + "-" + dt + Path.GetExtension(file));
using (FileStream destination = new FileStream(fn, FileMode.Create, FileAccess.Write))
{
long totalBytes = 0;
int currentBlockSize = 0;
while ((currentBlockSize = source.Read(buffer, 0, buffer.Length)) > 0)
{
totalBytes += currentBlockSize;
destination.Write(buffer, 0, currentBlockSize);
worker.ReportProgress((int)(100.0 * (double)totalBytes / fileLength));
}
}
}
}
else{
e.Cancel = true;
break;
}
}
break;
case DialogResult.Cancel:
e.Cancel = true;
this.backgroundWorker.CancelAsync();
break;
}
}
What is wrong with that? 怎么了 Do I need the invoke to read controls too?
我也需要调用才能读取控件吗? If yes, will really appreciate your help how to do that.
如果是的话,将非常感谢您的帮助。 Thank you.
谢谢。
[EDIT] I also tried this: [编辑]我也试过这个:
private BlockingCollection<ListView.CheckedListViewItemCollection> checkedItems = null;
...
this.checkedItems = new BlockingCollection<ListView.CheckedListViewItemCollection>();
foreach (ListView.CheckedListViewItemCollection item in this.listViewFiles.CheckedItems)
{
this.checkedItems.Add(item);
}
this.checkedItems.CompleteAdding();
but I have the following error at the foreach: "System.InvalidCastException: Unable to cast object of type 'System.Windows.Forms.ListViewItem' to type 'CheckedListViewItemCollection'." 但是我在foreach上遇到以下错误:“ System.InvalidCastException:无法将类型为“ System.Windows.Forms.ListViewItem”的对象强制转换为“ CheckedListViewItemCollection”。”
ListView.CheckedListViewItemCollection
is not a thread-safe collection. ListView.CheckedListViewItemCollection
不是线程安全的集合。 You're going to want to put the contents in something from the System.Collections.Concurrent
namespace, like ConcurrentBag<T>
or BlockingCollection<T>
. 您将想要将内容放入
System.Collections.Concurrent
命名空间中的内容中,例如ConcurrentBag<T>
或BlockingCollection<T>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.