跨线程操作问题 [英] Problem over cross thread operation

查看:57
本文介绍了跨线程操作问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个列表框,一个用于UI线程,另一个我需要在另一个线程上工作。第一个列表框用UI线程填充,添加完整元素后我需要将这些元素添加到另一个列表框中我应该为此做些什么。我为此编了代码,但是我得到了一个错误,比如在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。我可能会把代码片段放到写了



Rajeesh

谢谢和问候



I have two list boxes ,one works on UI thread and another I need to work on another thread.First List box is populated with UI thread,after adding the full elements I need to add those elements into another list box using another .What should I do for this.I have codded for this but I get an error like Invoke or BeginInvoke cannot be called on a control until the window handle has been created. I may put code snippet I have written

Rajeesh
Thanks and Regards

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ThreadApplication
{
    public partial class Form1 : Form
    {
       
        public Form1()
        {
            InitializeComponent();
         
        }


        private void button1_Click(object sender, EventArgs e)

        {
            try
            {
            label1.Text = Thread.CurrentThread.Name;
            string[] fruits;
            fruits = new string[5];
            fruits[0] = "Banana";
            fruits[1] = "Grape";
            fruits[2] = "Apple";
            fruits[3] = "Orange";
            fruits[4] = "Pappaya";

            foreach (var fruit in fruits)
            {
                listBox1.Items.Add(fruit);
                listBox1.Refresh();
            }

            var list = new ArrayList();
            list.AddRange(listBox1.Items);

             Thread  objNewThread = new Thread(new ParameterizedThreadStart(objAddFruits.ConsumerJob));
             
             objNewThread.Start(list);     
            
             Thread.Sleep(1000);

             MessageBox.Show("" + Thread.CurrentThread.Priority);
        

            }
            catch (Exception ex)
            {
                MessageBox.Show("" + ex.Message);
                throw;
            }

        }

        private void button2_Click(object sender, EventArgs e)
        { 
           //new ConsumerJobClass().ConsumerJob();
            
        }
      
        }



    public  class ConsumerJobClass :Form1
    {

        public  void ConsumerJob(object list)
        { 
            var frm=new Form1();
            
           ArrayList arrayList=(ArrayList)list;
         foreach (var item in arrayList)
            {
               if (!frm.IsHandleCreated)
                    frm.CreateControl();
 frm.listBox2.Invoke((MethodInvoker)delegate() { frm.listBox2.Items.Add(item); }); // I got Error here
                listBox2.Refresh();
                this.Invoke(new Action(() => listBox1.Items.Remove(item)));
                listBox1.Items.Remove(item);
                listBox1.Refresh(); 
               
             }

        }

    }


    }

推荐答案

甚至不要尝试这样做。

对于初学者来说,它不起作用:你创建一个新的表格实例在你的ConsumerJob方法中,所以即使它确实有效,它也不会更新显示。



相反,请考虑使用BackgroundWorker类:​​它提供了一种进给机制返回到通过ProgressChanged事件发起线程的表单,该infor可以包含e.UserState对象 - 它可以包含要用列表框更新列表框的数据。
Don't even try to do it like that.
For starters, it won't work: you create a new instance of the form in your ConsumerJob method, so even if it did work it wouldn't update the display.

Instead, consider using a BackgroundWorker class instead: it provides a mechanism for feeding progress back to the form that originated the thread via the ProgressChanged Event, and that infor can include the e.UserState object - which can contain the data you want to update the listboxes with.


这篇关于跨线程操作问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆