namespace Threadtest
{
    public partial class ShowForm : Form
    {
        public ShowForm()
        {
            InitializeComponent();
           
        }        private void ShowForm_Load(object sender, EventArgs e)
        {
            this.Controls.Add(tc);
        }
        public void ShowWeb(List<string> strUrls)
        {
            for (int i = 0; i < strUrls.Count; i++)
            {
                string objUrl = strUrls[i];
                ParameterizedThreadStart ps = new ParameterizedThreadStart(ThreadWeb);
                Thread th = new Thread(ps);
                th.SetApartmentState(ApartmentState.STA);
                th.Start((object)objUrl);
            }
        }
        TabControl tc = new TabControl();
        private void ThreadWeb(object objUrl)
        {
            string strUrl = (string)objUrl;
            WebBrowser web = new WebBrowser();
            web.Url = new Uri(strUrl);
            web.Dock = DockStyle.Fill;
            TabPage tp = new TabPage();
            tp.Controls.Add(web);
         
            tc.Controls.Add(tp);
        }
    }
}
tc不是在线程中创建的。有没有人知道怎么办?

解决方案 »

  1.   

    线程切换的问题.
    查看InvokeRequired 
      

  2.   

    谢谢楼上的。Invoke不会用。查了半天也没找到答案。能不能给个具体的答案。
      

  3.   

    delegate void SetText(Control C,String Text); void DoSetText(Control C,String Text) 

        C.Text=Text; 
    } SetTextWithDelegate(Control C,String Text) 

        SetText PSetText=new SetText(DoSetText); 
        if (C.InvokeRequired) 
            C.Invoke(PSetText,new Object[]{C,Text}); 
        else 
            C.Text=Text; 
    } SetTextWithDelegate(textBox1,"TEXT"); 
      

  4.   

    谢谢楼上的。能不能把我的程序加上Invoke,我真的不会用。
      

  5.   

    倒。
    namespace Threadtest 

        public partial class ShowForm : Form 
        { 
            public ShowForm() 
            { 
                InitializeComponent(); 
              
            }         private void ShowForm_Load(object sender, EventArgs e) 
            { 
                this.Controls.Add(tc); 
            } 
            public void ShowWeb(List <string> strUrls) 
            { 
                for (int i = 0; i < strUrls.Count; i++) 
                { 
                    string objUrl = strUrls[i]; 
                    ParameterizedThreadStart ps = new ParameterizedThreadStart(ThreadWeb); 
                    Thread th = new Thread(ps); 
                    th.SetApartmentState(ApartmentState.STA); 
                    th.Start((object)objUrl); 
                } 
            } 
            TabControl tc = new TabControl();         delegate void AddTabPage(TabControl TC,TabPage Page);         void DoAddTabPage(TabControl TC,TabPage Page) 
            { 
                TC.Add(Page);
            }         AddTabPageWithDelegate(TabControl TC,TabPage Page) 
            { 
                AddTabPage PAddTabPage=new AddTabPage(DoAddTabPage); 
                if (TC.InvokeRequired) 
                    TC.Invoke(PAddTabPage, new Object[]{ TC, Page }); 
                else 
                    TC.Add(Page);
            } 
            
            void ThreadWeb(object objUrl) 
            { 
                string strUrl = (string)objUrl; 
                WebBrowser web = new WebBrowser(); 
                web.Url = new Uri(strUrl); 
                web.Dock = DockStyle.Fill; 
                TabPage tp = new TabPage(); 
                tp.Controls.Add(web);             AddTabPageWithDelegate(tc,tp)       
            } 
        } 
      

  6.   

    不行啊!namespace Threadtest 

        public partial class ShowForm : Form 
        { 
            public ShowForm() 
            { 
                InitializeComponent(); 
              
            }         private void ShowForm_Load(object sender, EventArgs e) 
            { 
                this.Controls.Add(tc); 
            } 
            public void ShowWeb(List <string> strUrls) 
            { 
                for (int i = 0; i < strUrls.Count; i++) 
                { 
                    string objUrl = strUrls[i]; 
                    ParameterizedThreadStart ps = new ParameterizedThreadStart(ThreadWeb); 
                    Thread th = new Thread(ps); 
                    th.SetApartmentState(ApartmentState.STA); 
                    th.Start((object)objUrl); 
                } 
            } 
            TabControl tc = new TabControl();         delegate void AddTabPage(TabControl TC,TabPage Page);         void DoAddTabPage(TabControl TC,TabPage Page) 
            { 
                TC.Add(Page);
            }         AddTabPageWithDelegate(TabControl TC,TabPage Page) 
            { 
                AddTabPage PAddTabPage=new AddTabPage(DoAddTabPage); 
                if (TC.InvokeRequired)                 //线程间操作无效: 从不是创建控件“”的线程访问它。
                    TC.Invoke(PAddTabPage, new Object[]{ TC, Page }); 

                else 
                    TC.Add(Page);
            } 
            
            void ThreadWeb(object objUrl) 
            { 
                string strUrl = (string)objUrl; 
                WebBrowser web = new WebBrowser(); 
                web.Url = new Uri(strUrl); 
                web.Dock = DockStyle.Fill; 
                TabPage tp = new TabPage(); 
                tp.Controls.Add(web);             AddTabPageWithDelegate(tc,tp)       
            } 
        } 
      

  7.   

    namespace Threadtest 

        public partial class ShowForm : Form 
        { 
            public ShowForm() 
            { 
                InitializeComponent(); 
              
            }         private void ShowForm_Load(object sender, EventArgs e) 
            { 
                this.Controls.Add(tc); 
            } 
            public void ShowWeb(List <string> strUrls) 
            { 
                for (int i = 0; i < strUrls.Count; i++) 
                { 
                    string objUrl = strUrls[i]; 
                    ParameterizedThreadStart ps = new ParameterizedThreadStart(ThreadWeb); 
                    Thread th = new Thread(ps); 
                    th.SetApartmentState(ApartmentState.STA); 
                    th.Start((object)objUrl); 
                } 
            } 
            TabControl tc = new TabControl();         delegate void AddTabPage(TabControl TC,TabPage Page);         void DoAddTabPage(TabControl TC,TabPage Page) 
            { 
                TC.Controls.Add(Page);
            }         void AddTabPageWithDelegate(TabControl TC,TabPage Page) 
            { 
                AddTabPage PAddTabPage=new AddTabPage(DoAddTabPage); 
                if (TC.InvokeRequired)
                    //线程间操作无效: 从不是创建控件“”的线程访问它。 
                    TC.Invoke(PAddTabPage, new Object[]{ TC, Page }); 
                else 
                    TC.Controls.Add(Page);
            } 
            
            void ThreadWeb(object objUrl) 
            { 
                string strUrl = (string)objUrl; 
                WebBrowser web = new WebBrowser(); 
                web.Url = new Uri(strUrl); 
                web.Dock = DockStyle.Fill; 
                TabPage tp = new TabPage(); 
                tp.Controls.Add(web);            AddTabPageWithDelegate(tc, tp);    
            } 
        } 

      

  8.   

            AddTabPageWithDelegate(TabControl TC,TabPage Page) 
            { 
                AddTabPage PAddTabPage=new AddTabPage(DoAddTabPage); 
                if (Page.GetCurrentParent().InvokeRequired) 
                    Page.GetCurrentParent().Invoke(PAddTabPage, new Object[]{ TC, Page }); 
                else 
                    TC.Add(Page);
            } 
      

  9.   

     AddTabPageWithDelegate(TabControl TC,TabPage Page) 
            { 
                AddTabPage PAddTabPage=new AddTabPage(DoAddTabPage); 
                if (Page.InvokeRequired) 
                    Page.Invoke(PAddTabPage, new Object[]{ TC, Page }); 
                else 
                    TC.Add(Page);
            } 
    不好意思,没有GetCurrentParent 手头还在并行忙写别的代码,写得忙了点
      

  10.   

    不知道加上这句话行不行
    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
      

  11.   

    是应该用线程里创建的tp去invoke主线程的tc而不是返过来
      

  12.   

    这是我上次用这话的后果,偶尔地程序崩溃,后来读写界面控件的代码改用委托后就很稳定了未处理 System.AccessViolationException
      Message="尝试读取或写入受保护的内存。这通常指示其他内存已损坏。"
      Source="System.Windows.Forms"
      StackTrace:
           在 System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
           在 System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
           在 System.Windows.Forms.Control.DefWndProc(Message& m)
           在 System.Windows.Forms.Control.WndProc(Message& m)
           在 System.Windows.Forms.TextBoxBase.WndProc(Message& m)
           在 System.Windows.Forms.RichTextBox.WndProc(Message& m)
           在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           在 System.Windows.Forms.UnsafeNativeMethods.PeekMessage(MSG& msg, HandleRef hwnd, Int32 msgMin, Int32 msgMax, Int32 remove)
           在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           在 System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
           在 System.Windows.Forms.Form.ShowDialog()
           在 DSMT.ProcessData.ForegroundMonitor.frmRemotingLogin.BtnRomatingLogin_Click(Object sender, EventArgs e) 位置 D:\WANGTING\DMST.ProcessData\DSMT.ProcessData.ForegroundMonitor\frmRemotingLogin.cs:行号 65
           在 System.Windows.Forms.Control.OnClick(EventArgs e)
           在 System.Windows.Forms.Button.OnClick(EventArgs e)
           在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
           在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           在 System.Windows.Forms.Control.WndProc(Message& m)
           在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
           在 System.Windows.Forms.Button.WndProc(Message& m)
           在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           在 System.Windows.Forms.Application.Run(Form mainForm)
           在 DSMT.ProcessData.ForegroundMonitor.Program.Main() 位置 D:\WANGTING\DMST.ProcessData\DSMT.ProcessData.ForegroundMonitor\Program.cs:行号 17
           在 System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
           在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           在 System.Threading.ThreadHelper.ThreadStart()
      

  13.   

        public delegate void TestDelgate( string strUrl );
        public partial class ShowForm : Form
        {
            public ShowForm()
            {
                InitializeComponent();
            }        private void ShowForm_Load( object sender, EventArgs e )
            {
                this.Controls.Add( tc );
                List<string> strUrls = new List<string>();
                strUrls.Add( "http://topic.csdn.net/u/20080924/13/80570378-04d4-4993-99b4-dc8234f4a50d.html" );
                strUrls.Add( "http://cn.msn.com/" );
                ShowWeb( strUrls );
            }
            public void ShowWeb( List<string> strUrls )
            {
                for( int i = 0; i < strUrls.Count; i++ )
                {
                    string objUrl = strUrls[ i ];
                    ParameterizedThreadStart ps = new ParameterizedThreadStart( ThreadWeb );
                    Thread th = new Thread( ps );
                    th.SetApartmentState( ApartmentState.STA );
                    th.Start( ( object )objUrl );
                }
            }
            TabControl tc = new TabControl();
            private void ThreadWeb( object objUrl )
            {
                string strUrl = ( string )objUrl;
                TestDelgate test = new TestDelgate(this.TestMethod);
                this.Invoke( test, new object[] { strUrl } );
            }
            private void TestMethod( string strUrl )
            {
                WebBrowser web = new WebBrowser();
                web.Url = new Uri( strUrl );
                web.Dock = DockStyle.Fill;
                TabPage tp = new TabPage();
                tp.Controls.Add( web );
                tc.Controls.Add( tp );
            }别在线程里生成控件了。放在委托里生成。效果一样。
      

  14.   

    我也是用这个System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
    有时出错。
    这个不是解决之道,尽量少用。
      

  15.   

    谢谢了,说的没错,把变量都放在委托里。
    也谢谢wartim 。
    结贴给分了。
      

  16.   

    CheckForIllegalCrossThreadCalls = false;
      

  17.   


    加上这句话应该是可以的,我刚才的一个Demo也是这个问题,我加入这句话后运行正常了!