读书人

怎么在一个form窗体里开两个UI线程

发布时间: 2012-11-20 09:55:43 作者: rapoo

怎样在一个form窗体里开两个UI线程
我现在有个form有两个控件,一个是WebBrowser控件,一个是普通按钮控件A。我现在要做个调试网页功能,通过网页里window.external.Wait方法调用本地方法Wait,然后挂起网页,比如当网页运行到window.external.Wait方法时就把网页挂起来不让它继续执行。同时form里的普通按钮控件A可以操作恢复和挂起网页。 现在的问题是当我挂起网页时整个form窗体就处于假死状态。我想到的办法是开两个UI线程,一个UI线程A处理WebBrowser,另一个UI线程B处理form,当UI线程A挂起时,UI线程B可继续运行,并可挂起和恢复UI线程A。 但是现在Winform的机制好像是一个应用程序只能有一个UI线程,有没有其他办法解决这个问题,这问题困扰我好几天了,所有求助csdn各位牛人帮忙想想办法。

C# code
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication8{    [System.Runtime.InteropServices.ComVisibleAttribute(true)]    public  class Form1 : Form    {        private System.Windows.Forms.WebBrowser webBrowser1;        private System.Windows.Forms.Button button1;        /// <summary>        /// 必需的设计器变量。        /// </summary>        private System.ComponentModel.IContainer components = null;        public Form1()        {            InitializeComponent();            webBrowser1.ObjectForScripting = this;            webBrowser1.DocumentText = "<html><head><title></title> " +                "<script type=\"text/javascript\"> window.external.Wait();" +           " alert('test!'); </script> </head> <body> </body></html>";                        }        protected override void OnLoad(EventArgs e)        {                           }        private void button1_Click(object sender, EventArgs e)        {        }        public void Wait()         {//挂起后怎么才能让窗体不处于假死状态            System.Threading.Thread.CurrentThread.Suspend();        }        /// <summary>        /// 清理所有正在使用的资源。        /// </summary>        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>        protected override void Dispose(bool disposing)        {            if (disposing && (components != null))            {                components.Dispose();            }            base.Dispose(disposing);        }        #region Windows 窗体设计器生成的代码        /// <summary>        /// 设计器支持所需的方法 - 不要        /// 使用代码编辑器修改此方法的内容。        /// </summary>        private void InitializeComponent()        {            this.webBrowser1 = new System.Windows.Forms.WebBrowser();            this.button1 = new System.Windows.Forms.Button();            this.SuspendLayout();            //             // webBrowser1            //             this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Top;            this.webBrowser1.Location = new System.Drawing.Point(0, 0);            this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);            this.webBrowser1.Name = "webBrowser1";            this.webBrowser1.Size = new System.Drawing.Size(718, 204);            this.webBrowser1.TabIndex = 0;            //             // button1            //             this.button1.Location = new System.Drawing.Point(158, 224);            this.button1.Name = "button1";            this.button1.Size = new System.Drawing.Size(75, 23);            this.button1.TabIndex = 1;            this.button1.Text = "挂起恢复";            this.button1.UseVisualStyleBackColor = true;            this.button1.Click += new System.EventHandler(this.button1_Click);            //             // Form1            //             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;            this.ClientSize = new System.Drawing.Size(718, 283);            this.Controls.Add(this.button1);            this.Controls.Add(this.webBrowser1);            this.Name = "Form1";            this.Text = "Form1";            this.ResumeLayout(false);        }        #endregion    }    static class Program    {        /// <summary>        /// 应用程序的主入口点。        /// </summary>        [STAThread]        static void Main()        {            Application.EnableVisualStyles();            Application.SetCompatibleTextRenderingDefault(false);            Application.Run(new Form1());        }    }} 



[解决办法]
UI线程,也就是主线程只有一个吧
[解决办法]
探讨

引用:

添加个允许跨线程访问控件,把要操作的代码块放在新线程里面试试。
CheckForIllegalCrossThreadCalls = false;


我的目的不是跨线程访问控件,而是挂起webBrowser控件时,界面的上的其他控件可以继续操作。

[解决办法]
C# code
        private void button1_Click(object sender, EventArgs e)        {            Thread t = new Thread(Test);            t.Start();        }        private void button2_Click(object sender, EventArgs e)        {            Thread t = new Thread(Test);            t.Start();        }        private void Test()        {            Thread.Sleep(3000);        }
[解决办法]
你这样写直接把主线程挂起了,估计无解。
是不是可以换种思路呢?
[解决办法]
C# code
        private void DoWait()        {            Thread t = new Thread(Wait);            t.Start();        }        public void Wait()         {            //挂起后怎么才能让窗体不处于假死状态            System.Threading.Thread.CurrentThread.Suspend();        }        //window.external.DoWait();
[解决办法]
探讨

引用:
你这样写直接把主线程挂起了,估计无解。
是不是可以换种思路呢?
可以,不管用什么方法只要达到我上面的目的就行,可以把我的上面的代码放到vs跑下,跑通了再找我,呵呵。

[解决办法]
用异步线程,然后使用委托,跨线程操作就可以了。
[解决办法]
能否换个思路?把web控件放到另一个窗体上,然后用另一个线程启动这个窗体,来控制?
C# code
namespace WindowsFormsApplication1{    partial class Form1    {        /// <summary>        /// 必需的设计器变量。        /// </summary>        private System.ComponentModel.IContainer components = null;        /// <summary>        /// 清理所有正在使用的资源。        /// </summary>        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>        protected override void Dispose(bool disposing)        {            if (disposing && (components != null))            {                components.Dispose();            }            base.Dispose(disposing);        }        #region Windows 窗体设计器生成的代码        /// <summary>        /// 设计器支持所需的方法 - 不要        /// 使用代码编辑器修改此方法的内容。        /// </summary>        private void InitializeComponent()        {            this.button1 = new System.Windows.Forms.Button();            this.webBrowser1 = new System.Windows.Forms.WebBrowser();            this.SuspendLayout();            //             // button1            //             this.button1.Location = new System.Drawing.Point(12, 12);            this.button1.Name = "button1";            this.button1.Size = new System.Drawing.Size(75, 23);            this.button1.TabIndex = 0;            this.button1.Text = "假死";            this.button1.UseVisualStyleBackColor = true;            this.button1.Click += new System.EventHandler(this.button1_Click);            //             // webBrowser1            //             this.webBrowser1.Location = new System.Drawing.Point(93, 12);            this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);            this.webBrowser1.Name = "webBrowser1";            this.webBrowser1.Size = new System.Drawing.Size(234, 306);            this.webBrowser1.TabIndex = 1;            //             // Form1            //             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;            this.ClientSize = new System.Drawing.Size(494, 330);            this.Controls.Add(this.webBrowser1);            this.Controls.Add(this.button1);            this.Name = "Form1";            this.Text = "Form1";            this.ResumeLayout(false);        }        #endregion        private System.Windows.Forms.Button button1;        private System.Windows.Forms.WebBrowser webBrowser1;    }} 


[解决办法]

探讨
引用:
添加个允许跨线程访问控件,把要操作的代码块放在新线程里面试试。
CheckForIllegalCrossThreadCalls = false;

我的目的不是跨线程访问控件,而是挂起webBrowser控件时,界面的上的其他控件可以继续操作。

读书人网 >C#

热点推荐