从Backgroundworker_DoWork访问ImageList1而不使用C#的任何“委托”

时间:2013-12-25 05:57:39

标签: c# winforms backgroundworker imagelist

我有使用Net 2的C#系统Windows窗体(我只是初学者所以请耐心等待)并希望将Backgroundworker-Process中的图像添加到我的Form1上的ImageList1,以避免GUI冻结而文件名图标从一个包含10000多个文件的大目录中,在ListView中显示文件名和图标 我存储在列表中的文件名,并使用AddRange方法将它们添加到Backgroundworker-Finished Event中。图像无法以这种方式存储或丢失质量。我必须直接在DoWork()事件部分中将它们添加到Backgroundworker-Process中。并且存在一个问题:在我的免费版Microsoft Visual Studio 2008中出现了一条很长的错误消息,其中包含类似于此的奇怪内容:Cannot access ImageList1 because it was created in another thread...????
我打开了一张微软票,他们回答我,这是免费版的一个问题,一个bug。是这样还是你可以帮助我。我在谷歌发现了一些关于任何“代表”的事情,但我恐怕我很少知道如何利用这种结构。我只知道如何声明一个“int”,一个字符串和一个列表,更多的不是,我可以在我的表单上放置一些用户控件或在事件中填充一些简单的代码。也许你们中的某个人有类似的问题,并且可以提出一个可以使用的准确可理解的解决方案。我如何抑制关于ImageList中其他线程的错误?也许在C#中存在类似“On Error Resume Next”的语句,它强制执行代码无论如何都要继续。然后许多VB6应用程序将能够再次运行在夏普,dunno ofc。请帮忙。

2 个答案:

答案 0 :(得分:0)

这是一种方法:

  1. 创建一个Action,并在Action中放置访问ImageList1的代码。
  2. 在后台工作人员的DoWork上,使用ImageList1.Invoke(ActionNameHere)替换已移至操作的代码。

  3. 这是一个简化的示例,代码将从backgroundworker更新Label的Text属性:

    Action act = () =>
                  {
                      label1.Text = "Test updating UI property from background thread";
                  };
    worker.DoWork += (o, args) =>
                 {
                     label1.Invoke(act);
                 };
    worker.RunWorkerAsync();
    

答案 1 :(得分:0)

你没有发布你的代码,所以这是我建议你可以使用的代码片段,它应该有效:

使用backgroundWorker时,我总是方便地使用@Keith template

BackgroundWorker bw = new BackgroundWorker { WorkerReportsProgress = true };

bw.DoWork += (sender, e) => 
   {
       //what happens here must not touch the form
       //as it's in a different thread

        Action AccessImageList = () => { int count = imgLst.Images.Count;//access the image list };
        this.Invoke(AccessImageList, new object[] { });
   };

bw.ProgressChanged += ( sender, e ) =>
   {
       //update progress bars here
   };

bw.RunWorkerCompleted += (sender, e) => 
   {
       //now you're back in the UI thread you can update the form
       //remember to dispose of bw now
   };

worker.RunWorkerAsync();