簡體   English   中英

C#-跨線程操作無效。 控制ListView…和背景工作人員

[英]C# - Cross-thread operation not valid. Control ListView…and backgroundworker

我有一個背景工作者從ListView復制文件。 我讀過許多類似的問題,但它們似乎都與試圖更改UI控件的DoWork屬性有關。 我什么都沒改變。 我只是瀏覽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;
        }
    }

怎么了 我也需要調用才能讀取控件嗎? 如果是的話,將非常感謝您的幫助。 謝謝。

[編輯]我也試過這個:

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

但是我在foreach上遇到以下錯誤:“ System.InvalidCastException:無法將類型為“ System.Windows.Forms.ListViewItem”的對象強制轉換為“ CheckedListViewItemCollection”。”

ListView.CheckedListViewItemCollection不是線程安全的集合。 您將想要將內容放入System.Collections.Concurrent命名空間中的內容中,例如ConcurrentBag<T>BlockingCollection<T>

MSDN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM