这个简短的多线程代码有问题怎么修改?

ooolinux 2017-11-10 11:17:20
功能是计算3个数字显示在3个TextBox上,其中一个大数的计算使用单独的线程,主要代码如下:

    public partial class Frm_Main : Form
{
public Frm_Main()
{
InitializeComponent();
}

Thread myThread;

public delegate void AddFile();

public void SetAddFile()
{
this.Invoke(new AddFile(RunAddFile));
}

public void RunAddFile()
{
textBox2.Text = Power(7, 50).ToString(); //大数长时间计算
Thread.Sleep(0);
myThread.Abort();
}

private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = Power(2, 4).ToString();//计算2的4次幂
myThread = new Thread(new ThreadStart(SetAddFile));//创建线程对象
myThread.Start(); //开始运行线程
textBox3.Text = Power(2, 2).ToString();//计算2的2次幂
}


代码有问题怎么修改呢?
Thread.Sleep(0); 这句作用是什么?
myThread.Abort(); 这句有必要吗?
...全文
390 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2017-11-15
  • 打赏
  • 举报
回复
如果要在退出时,让线程一起退出,可以设置线程为 IsBackground = true; 使其成为后台线程
正怒月神 2017-11-15
  • 打赏
  • 举报
回复
代码有问题怎么修改呢? 没什么大问题 Thread.Sleep(0); 这句作用是什么? thread.sleep(0) 作用在于,让出cpu,让其他线程可以跑起来。 相当于一个通知。 myThread.Abort(); 这句有必要吗? 没必要。
ooolinux 2017-11-15
  • 打赏
  • 举报
回复
引用 13 楼 hanjun0612 的回复:
如果要在退出时,让线程一起退出,可以设置线程为 IsBackground = true; 使其成为后台线程
好的,明白了。
ooolinux 2017-11-14
  • 打赏
  • 举报
回复
@wanglantian1 谢谢,m_Thread.Abort(); 时需要判断ThreadState吗?
望蓝天 2017-11-14
  • 打赏
  • 举报
回复
引用 9 楼 u010165006 的回复:
@wanglantian1 谢谢,如果关闭程序的时候,创建的myThread 线程可能没有计算完毕,怎么写代码手动结束它呢,写在哪个窗体事件里比较合适呢? 有没有一本书的多线程章节的例子跟窗体有关的,比较完善的,推荐一下有吗?
学习多线程的话感觉还是看论坛把,我也没有什么特别合适的书推荐。 如果想要结束线程的话就调用m_Thread.Abort();这会强制中断线程,引发一个线程中的异常,你捕获它然后什么都不做就退出了。你可以百度下Thread.Abort(),有很多说明的。
ooolinux 2017-11-13
  • 打赏
  • 举报
回复
@wanglantian1 我现在能理解你说的了,不过原代码感觉不好,我修改了一下,
    public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }

        Thread myThread;

        private delegate void deCalc(double d);

        private void funCalc(double d)
        {
            textBox2.Text = d.ToString();
        }
        private void calc()
        {
            double d = 1.0;
            for (int i = 0; i < 99999999; i++)
            {
                d *= Math.Pow(7, 50);
            }
            this.Invoke(new deCalc(funCalc), d);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = Math.Pow(2, 4).ToString();
            myThread = new Thread(new ThreadStart(calc));
            myThread.Start();                          
            textBox3.Text = Math.Pow(2, 2).ToString();
        }
    }
这样有问题吗(主要Invoke那里)?如果myThread 线程未计算完,关闭窗口结束程序,myThread 会自动结束吗?
ooolinux 2017-11-13
  • 打赏
  • 举报
回复
@wanglantian1 谢谢,如果关闭程序的时候,创建的myThread 线程可能没有计算完毕,怎么写代码手动结束它呢,写在哪个窗体事件里比较合适呢? 有没有一本书的多线程章节的例子跟窗体有关的,比较完善的,推荐一下有吗?
ooolinux 2017-11-13
  • 打赏
  • 举报
回复
@closurer
望蓝天 2017-11-13
  • 打赏
  • 举报
回复
引用 6 楼 u010165006 的回复:
@wanglantian1 我现在能理解你说的了,不过原代码感觉不好,我修改了一下,
    public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }

        Thread myThread;

        private delegate void deCalc(double d);

        private void funCalc(double d)
        {
            textBox2.Text = d.ToString();
        }
        private void calc()
        {
            double d = 1.0;
            for (int i = 0; i < 99999999; i++)
            {
                d *= Math.Pow(7, 50);
            }
            this.Invoke(new deCalc(funCalc), d);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = Math.Pow(2, 4).ToString();
            myThread = new Thread(new ThreadStart(calc));
            myThread.Start();                          
            textBox3.Text = Math.Pow(2, 2).ToString();
        }
    }
这样有问题吗(主要Invoke那里)?如果myThread 线程未计算完,关闭窗口结束程序,myThread 会自动结束吗?
没有问题啊,跨线程访问控件嘛。如果线程未运行结束,关闭程序,你可以在任务管理器里面看到进程还在,所以不会线程不会退出的。你可以通过在关闭的时候调用Environment.Exit(0)清空所有资源。
ooolinux 2017-11-12
  • 打赏
  • 举报
回复
引用 1 楼 wanglantian1 的回复:
我试了试,代码应该是没有问题的。在我上面唯一的问题是Power()找不到定义,我用的是Math.Pow()。 Thread.Sleep(0);我觉得应该是让主线程主动让出CPU运行时间来给myThread。 当程序执行到this.Invoke(new AddFile(RunAddFile));时,在主线程调用RunAddFile,Thread.Sleep(0);回到this.Invoke(new AddFile(RunAddFile));,继续执行,函数结束,myThread线程结束,这时候执行主线程,到Thread.Sleep(0)的下一步,调用myThread.Abort(); 强制退出myThread线程。 在我看来,myThread.Abort()这句可以不要。个人认识。
这个代码来自《C#经典编程220例(明日科技)》多线程一章的例子,函数命名不知道怎么抄的, Thread.Sleep 我查了下是挂起当前线程一段时间,当前线程是不是指运行该代码的线程呢? 我觉得问题是,this.Invoke(new AddFile(RunAddFile)); RunAddFile是长时间计算的,是不是会阻塞UI线程造成界面无响应?Thread.Sleep(0);作者的意思是不是挂起当前线程让UI线程得到执行从而能够刷新界面?
望蓝天 2017-11-12
  • 打赏
  • 举报
回复
引用 2 楼 u010165006 的回复:
[quote=引用 1 楼 wanglantian1 的回复:] 我试了试,代码应该是没有问题的。在我上面唯一的问题是Power()找不到定义,我用的是Math.Pow()。 Thread.Sleep(0);我觉得应该是让主线程主动让出CPU运行时间来给myThread。 当程序执行到this.Invoke(new AddFile(RunAddFile));时,在主线程调用RunAddFile,Thread.Sleep(0);回到this.Invoke(new AddFile(RunAddFile));,继续执行,函数结束,myThread线程结束,这时候执行主线程,到Thread.Sleep(0)的下一步,调用myThread.Abort(); 强制退出myThread线程。 在我看来,myThread.Abort()这句可以不要。个人认识。
这个代码来自《C#经典编程220例(明日科技)》多线程一章的例子,函数命名不知道怎么抄的, Thread.Sleep 我查了下是挂起当前线程一段时间,当前线程是不是指运行该代码的线程呢? 我觉得问题是,this.Invoke(new AddFile(RunAddFile)); RunAddFile是长时间计算的,是不是会阻塞UI线程造成界面无响应?Thread.Sleep(0);作者的意思是不是挂起当前线程让UI线程得到执行从而能够刷新界面?[/quote] invoke方法是在方法在当前线程执行,this.Invoke()就是让这个函数在主线程上执行。所以我觉得不是你说的这样,刷新主界面用,我觉得这边调用Invoke是为了跨线程访问控件。置于Thread.Sleep()的作用,我还是坚持原来的看法。
闭包客 2017-11-12
  • 打赏
  • 举报
回复
很无语,上面的回复我是回答另外一个帖子的,请忽略。
闭包客 2017-11-12
  • 打赏
  • 举报
回复
事务执行成功与否,用一个标识来表示。
望蓝天 2017-11-11
  • 打赏
  • 举报
回复
我试了试,代码应该是没有问题的。在我上面唯一的问题是Power()找不到定义,我用的是Math.Pow()。 Thread.Sleep(0);我觉得应该是让主线程主动让出CPU运行时间来给myThread。 当程序执行到this.Invoke(new AddFile(RunAddFile));时,在主线程调用RunAddFile,Thread.Sleep(0);回到this.Invoke(new AddFile(RunAddFile));,继续执行,函数结束,myThread线程结束,这时候执行主线程,到Thread.Sleep(0)的下一步,调用myThread.Abort(); 强制退出myThread线程。 在我看来,myThread.Abort()这句可以不要。个人认识。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧