none
在另一个类中CancelAsync主窗体中正在运行的backgroundWorker RRS feed

  • 问题

  • 举个例子:

    主窗体代码如下:

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace backgroundWorkerTest
    {
        public partial class MainForm : Form
        {
            public MainForm()
            {
                InitializeComponent();
            }
    
            Transfer tran;
    
            private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
            {
                this.toolStripStatusLabel1.Text = "运行";
                BackgroundWorker worker = sender as BackgroundWorker;
                tran = new Transfer(Convert.ToInt32(textBox1.Text));
                tran.D_Transfer();
            }
    
            private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message);
                    return;
                }
                if (e.Cancelled)
                {
                    this.toolStripStatusLabel1.Text = "取消";
                    textBox2.Text = tran.I.ToString();
                    return;
                }
                toolStripStatusLabel1.Text = "完成";
                textBox2.Text = tran.I.ToString();
            }
    
            private void btnS_Click(object sender, EventArgs e)
            {
                if (!this.bgWorker.IsBusy)
                {
                    this.bgWorker.RunWorkerAsync();
                }
            }
    
            private void btnC_Click(object sender, EventArgs e)
            {
                if (this.bgWorker.IsBusy)
                {
                    this.bgWorker.CancelAsync();
                }
            }
        }
    }

    另一个类的代码如下:

    namespace backgroundWorkerTest
    {
        public class Transfer
        {
            public Transfer()
            {
            }
            public Transfer(int I)
            {
                a = I;
            }
    
            private int a;
            public int I
            {
                get { return a; }
                set { a = value; }
            }
            public void D_Transfer()
            {
                do
                {
                    a = a * a;
                } while (a < 100);
            }
        }
    }
    

    当输入textBox1中输入大于1的数都没有问题,但是当输入0或是1时,程序就进入类Transfer中D_Transfer方法中do...while语句中不停的循环,这时按Cancel按钮并不能取消backgroundWorker?该如何修改代码?


    努力~

    2013年3月27日 6:58

答案

  • 你输入0或者1,那么显然Do……While这一块死循环了(永远条件不成立)。

    public partial class Form1 : Form
        {
            public class Transfer
            {
                public Transfer()
                {
                }
                public Transfer(int I)
                {
                    a = I;
                }
     
                private int a;
                public int I
                {
                    get { return a; }
                }
                public void D_Transfer(BackgroundWorker bw,DoWorkEventArgs e)
                {
                    do
                    {
                        a *= a;
                        if (bw.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }
                    } while (a < 100);
                }
            }
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object senderEventArgs e)
            {
                backgroundWorker1.WorkerSupportsCancellation = true;
            }
            Transfer tran;
     
            private void bgWorker_DoWork(object senderDoWorkEventArgs e)
            {
                tran.D_Transfer(backgroundWorker1,e);
            }
     
            private void bgWorker_RunWorkerCompleted(object senderRunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message);
                    return;
                }
                if (e.Cancelled)
                {
                    MessageBox.Show("取消");
                    textBox2.Text = tran.I.ToString();
                    return;
                }
                MessageBox.Show("完成");
                textBox2.Text = tran.I.ToString();
            }
     
            private void btnS_Click(object senderEventArgs e)
            {
                if (!this.backgroundWorker1.IsBusy)
                {
                    tran = new Transfer(Convert.ToInt32(textBox1.Text));
                    this.backgroundWorker1.RunWorkerAsync();
                }
            }
     
            private void btnC_Click(object senderEventArgs e)
            {
                if (this.backgroundWorker1.IsBusy)
                {
                    this.backgroundWorker1.CancelAsync();
                }
            }
        }

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    • 已标记为答案 zjyh16 2013年3月27日 9:23
    2013年3月27日 9:08
    版主
  • 总而言之,不能存在死循环。必须有终止条件(例如if+break)。

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    • 已标记为答案 zjyh16 2013年3月28日 7:14
    2013年3月28日 6:53
    版主
  • 这个变量应该是类级别的公共变量,放入第一层循环中。然后在Cancel按钮中设置数值即可。

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    • 已标记为答案 zjyh16 2013年4月1日 9:24
    2013年3月28日 7:16
    版主

全部回复

  • 你输入0或者1,那么显然Do……While这一块死循环了(永远条件不成立)。

    public partial class Form1 : Form
        {
            public class Transfer
            {
                public Transfer()
                {
                }
                public Transfer(int I)
                {
                    a = I;
                }
     
                private int a;
                public int I
                {
                    get { return a; }
                }
                public void D_Transfer(BackgroundWorker bw,DoWorkEventArgs e)
                {
                    do
                    {
                        a *= a;
                        if (bw.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }
                    } while (a < 100);
                }
            }
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object senderEventArgs e)
            {
                backgroundWorker1.WorkerSupportsCancellation = true;
            }
            Transfer tran;
     
            private void bgWorker_DoWork(object senderDoWorkEventArgs e)
            {
                tran.D_Transfer(backgroundWorker1,e);
            }
     
            private void bgWorker_RunWorkerCompleted(object senderRunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message);
                    return;
                }
                if (e.Cancelled)
                {
                    MessageBox.Show("取消");
                    textBox2.Text = tran.I.ToString();
                    return;
                }
                MessageBox.Show("完成");
                textBox2.Text = tran.I.ToString();
            }
     
            private void btnS_Click(object senderEventArgs e)
            {
                if (!this.backgroundWorker1.IsBusy)
                {
                    tran = new Transfer(Convert.ToInt32(textBox1.Text));
                    this.backgroundWorker1.RunWorkerAsync();
                }
            }
     
            private void btnC_Click(object senderEventArgs e)
            {
                if (this.backgroundWorker1.IsBusy)
                {
                    this.backgroundWorker1.CancelAsync();
                }
            }
        }

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    • 已标记为答案 zjyh16 2013年3月27日 9:23
    2013年3月27日 9:08
    版主
  • 非常感谢您的帮助!有问题再请教。

    努力~

    2013年3月27日 9:23
  • 你输入0或者1,那么显然Do……While这一块死循环了(永远条件不成立)。

    public partial class Form1 : Form
        {
            public class Transfer
            {
                public Transfer()
                {
                }
                public Transfer(int I)
                {
                    a = I;
                }
     
                private int a;
                public int I
                {
                    get { return a; }
                }
                public void D_Transfer(BackgroundWorker bw,DoWorkEventArgs e)
                {
                    do
                    {
                        a *= a;
                        if (bw.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }
                    } while (a < 100);
                }
            }
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object senderEventArgs e)
            {
                backgroundWorker1.WorkerSupportsCancellation = true;
            }
            Transfer tran;
     
            private void bgWorker_DoWork(object senderDoWorkEventArgs e)
            {
                tran.D_Transfer(backgroundWorker1,e);
            }
     
            private void bgWorker_RunWorkerCompleted(object senderRunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message);
                    return;
                }
                if (e.Cancelled)
                {
                    MessageBox.Show("取消");
                    textBox2.Text = tran.I.ToString();
                    return;
                }
                MessageBox.Show("完成");
                textBox2.Text = tran.I.ToString();
            }
     
            private void btnS_Click(object senderEventArgs e)
            {
                if (!this.backgroundWorker1.IsBusy)
                {
                    tran = new Transfer(Convert.ToInt32(textBox1.Text));
                    this.backgroundWorker1.RunWorkerAsync();
                }
            }
     
            private void btnC_Click(object senderEventArgs e)
            {
                if (this.backgroundWorker1.IsBusy)
                {
                    this.backgroundWorker1.CancelAsync();
                }
            }
        }

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    版主,你好。请问一下,现在只有一个Do。。。While循环,这时那个break会跳出Do……While这一块死循环,如果Do……While外面再嵌套着一个While的死循环,比如:

    while (a==0)
    {
    	do
            {
    	     if (bw.CancellationPending)
    	     {
    	        e.Cancel = true;
    	        break;
    	     }
    	     a *= a;
    	} while (a < 100);
    }

    此时输入0,点取消也取消不了bgWorker,此时程序是不是就会一直进入执行下面这一段代码?也就是说是不是只是跳出第一层循环,然后在执行第二层循环时又重新进入第一层循环。

    if (bw.CancellationPending)
    {
        e.Cancel = true;
        break;
    }

    怎么才能跳出最外层的循环呢?


    努力~

    2013年3月28日 6:52
  • 总而言之,不能存在死循环。必须有终止条件(例如if+break)。

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    • 已标记为答案 zjyh16 2013年3月28日 7:14
    2013年3月28日 6:53
    版主
  • 你输入0或者1,那么显然Do……While这一块死循环了(永远条件不成立)。

    public partial class Form1 : Form
        {
            public class Transfer
            {
                public Transfer()
                {
                }
                public Transfer(int I)
                {
                    a = I;
                }
     
                private int a;
                public int I
                {
                    get { return a; }
                }
                public void D_Transfer(BackgroundWorker bw,DoWorkEventArgs e)
                {
                    do
                    {
                        a *= a;
                        if (bw.CancellationPending)
                        {
                            e.Cancel = true;
                            break;
                        }
                    } while (a < 100);
                }
            }
            public Form1()
            {
                InitializeComponent();
            }
     
            private void Form1_Load(object senderEventArgs e)
            {
                backgroundWorker1.WorkerSupportsCancellation = true;
            }
            Transfer tran;
     
            private void bgWorker_DoWork(object senderDoWorkEventArgs e)
            {
                tran.D_Transfer(backgroundWorker1,e);
            }
     
            private void bgWorker_RunWorkerCompleted(object senderRunWorkerCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message);
                    return;
                }
                if (e.Cancelled)
                {
                    MessageBox.Show("取消");
                    textBox2.Text = tran.I.ToString();
                    return;
                }
                MessageBox.Show("完成");
                textBox2.Text = tran.I.ToString();
            }
     
            private void btnS_Click(object senderEventArgs e)
            {
                if (!this.backgroundWorker1.IsBusy)
                {
                    tran = new Transfer(Convert.ToInt32(textBox1.Text));
                    this.backgroundWorker1.RunWorkerAsync();
                }
            }
     
            private void btnC_Click(object senderEventArgs e)
            {
                if (this.backgroundWorker1.IsBusy)
                {
                    this.backgroundWorker1.CancelAsync();
                }
            }
        }

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    版主,你好。请问一下,现在只有一个Do。。。While循环,这时那个break会跳出Do……While这一块死循环,如果Do……While外面再嵌套着一个While的死循环,比如:

    while (a==0)
    {
    	do
            {
    	     if (bw.CancellationPending)
    	     {
    	        e.Cancel = true;
    	        break;
    	     }
    	     a *= a;
    	} while (a < 100);
    }

    此时输入0,点取消也取消不了bgWorker,此时程序是不是就会一直进入执行下面这一段代码?也就是说是不是只是跳出第一层循环,然后在执行第二层循环时又重新进入第一层循环。

    if (bw.CancellationPending)
    {
        e.Cancel = true;
        break;
    }

    怎么才能跳出最外层的循环呢?


    努力~

    是否在

    if (bw.CancellationPending) 
    { 
        e.Cancel = true; 
        break; 
    }

    增加一个bool变量,先跳出第一层循环,然后将变量置为true,第二层循环是再判断这个bool变量,如果为true则跳出循环,这样是否可行呢?有没有简单点的办法直接跳出所有循环?


    • 已编辑 zjyh16 2013年3月28日 7:13
    2013年3月28日 7:11
  • 这个变量应该是类级别的公共变量,放入第一层循环中。然后在Cancel按钮中设置数值即可。

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats

    • 已标记为答案 zjyh16 2013年4月1日 9:24
    2013年3月28日 7:16
    版主