这个简短代码的Thread是指myThread还是主线程?

ooolinux 2017-11-13 12:53:56
        Thread myThread;

private delegate void deCalc(double d);

private void funCalc(double d)
{
textBox2.Text = d.ToString();
Thread.Sleep(0); //这里的Thread是指myThread还是主线程呢?
}
private void calc()
{
double d = 1.0;
this.Invoke(new deCalc(funCalc), d);
}

private void button1_Click(object sender, EventArgs e)
{
myThread = new Thread(new ThreadStart(calc));
myThread.Start();
}
}


这个代码没什么用,Thread.Sleep(0); //这里的Thread是指myThread还是主线程呢?
this.Invoke(new deCalc(funCalc), d); 这句代码有没有什么副作用?
...全文
727 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
JimCarter 2017-11-14
  • 打赏
  • 举报
回复
引用 22 楼 u010165006 的回复:
还有一个问题,如果关闭程序的时候,创建的myThread 线程可能没有计算完毕,怎么写代码手动结束它呢,写在哪个窗体事件里比较合适呢? 有讲到多线程章节的书,有没有一本书的例子跟窗体有关的,比较完善的,推荐一下有吗?
new myThread的时候 设置myThread.isbackground=true.这样主线程结束的时候会自动结束掉子线程(会调用子线程的abort())。 更进一步,在你主窗体的form.closing事件中(或closed事件),调用myThread.abort(),手动结束你的子线程。
exception92 2017-11-14
  • 打赏
  • 举报
回复
引用 18 楼 u010165006 的回复:
[quote=引用 15 楼 duanzi_peng 的回复:] 既然认为主线程,如果sleep了,你认为是不是程序不会继续执行?等到挂起结束才继续执行?
Sleep时间到,挂起/睡眠状态就会转为就绪状态吧,然后操作系统会调度它执行。不知道理解有没误?[/quote]

 Task.Run(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("结果1");
            });
            Task.Run(() =>
            {
                Console.WriteLine("结果2");
            });
上述代码中的Thread.Sleep 挂起的是 Run中 匿名函数 所在的线程,而不是主线程!这样才会先输出结果2,再输出结果1。
ooolinux 2017-11-14
  • 打赏
  • 举报
回复
引用 37 楼 catshitone 的回复:
[quote=引用 36 楼 u010165006 的回复:] @catshitone 明白了,谢谢,如果手动结束myThread,直接Abort不要判断一下对象和线程状态吗,完整代码怎样的呢?
if(myThread.IsAlive) { myThread.Abort(); }[/quote] 好,前面可以 if(myThread) 吗?需要判断ThreadState吗?
JimCarter 2017-11-14
  • 打赏
  • 举报
回复
引用 36 楼 u010165006 的回复:
@catshitone 明白了,谢谢,如果手动结束myThread,直接Abort不要判断一下对象和线程状态吗,完整代码怎样的呢?
if(myThread.IsAlive) { myThread.Abort(); }
ooolinux 2017-11-14
  • 打赏
  • 举报
回复
@catshitone 明白了,谢谢,如果手动结束myThread,直接Abort不要判断一下对象和线程状态吗,完整代码怎样的呢?
ooolinux 2017-11-14
  • 打赏
  • 举报
回复
@duanzi_peng 你这个代码中,虽然我不清楚Task是什么,但是跟Invoke无关的吧。
ooolinux 2017-11-13
  • 打赏
  • 举报
回复
@peng2739956 楼主貌似是搞C++的,难道要转C#了吗 —————— 也没有搞C++,我原来学了点C++ Builder,现在想学下C#。
ooolinux 2017-11-13
  • 打赏
  • 举报
回复
@yangliu0512 @hdt @catshitone @duanzi_peng @From_TaiWan @sp1234 谢谢大家回答,原来理解有误,这个代码里Thread.Sleep()挂起的当前线程,当前线程是主线程还是myThread,说法/看法不一致亚?
peng2739956 2017-11-13
  • 打赏
  • 举报
回复
楼主貌似是搞C++的,难道要转C#了吗
  • 打赏
  • 举报
回复
引用 楼主 u010165006 的回复:
这里的Thread是指myThread还是主线程呢?
Thread 是类型名,并不是指任何线程实例。只不过 Sleep 这个方法是对当前线程进行阻塞,而并不是什么 Thread 来指称的。
秋的红果实 2017-11-13
  • 打赏
  • 举报
回复
Thread.Sleep(0); 是对主线程的 this.Invoke(new deCalc(funCalc), d); this指当前对象,假如你的是form程序,那么就是调用窗体的invoke方法,等于直接调用,没什么作用
exception92 2017-11-13
  • 打赏
  • 举报
回复
那个线程调用就挂起那个线程,不是针对某个线程。 主线程 是程序刚启动时创建的,也就一般的执行到main入口时创建的,所说的thread 指的后台/前台线程, 它们的区别是是否设置isbackground为true。 Threed.Sleep 会挂起当前调用者所在的线程,也就是funCalc所在的myThread. PS:个人观点,欢迎指正。
JimCarter 2017-11-13
  • 打赏
  • 举报
回复
Thread.sleep(),放到哪个线程里执行,就sleep哪个线程。 你给的例子里,是sleep主线程。你也可以试下Thread.sleep(5000),发现主线程就会有卡顿。
真相重于对错 2017-11-13
  • 打赏
  • 举报
回复
所以sleep执行在那个函数中,那个函数所在的线程,就是它起作用的线程。
真相重于对错 2017-11-13
  • 打赏
  • 举报
回复
sleep 是thread类的静态函数,所以Thread指的是Thread类,而不是具体某个对象 sleep作用是把当前线程挂起一定时间。
ooolinux 2017-11-13
  • 打赏
  • 举报
回复
@catshitone 麻烦帮我看一下22楼,谢谢
ooolinux 2017-11-13
  • 打赏
  • 举报
回复
@catshitone 谢,我也觉得简单的Invoke就可以了。
FainSheeg 2017-11-13
  • 打赏
  • 举报
回复
主线程的,这个过程只是正好被mythread委托用来更新主线程的界面而已。也很好理解,正是因为它是属于主线程的才能被委托用来更新主线程UI
JimCarter 2017-11-13
  • 打赏
  • 举报
回复
引用 28 楼 u010165006 的回复:
[quote=引用 25 楼 catshitone 的回复:] this.invoke方法没什么副作用,只是把某项操作移交给主线程来做。如:你在myThread里计算了一个值,想更新到Textbox上,肯定不能直接写textbox.text="123".要写成this.inovke(()=>{textbox.text="123";});(全凭记忆,差不多是这个意思)。因为你直接写的话,相当于其他线程要更新UI,而UI是在主线程里的,直接操作就会报异常。 返回你给的那个例子:我觉得你新建一个myThread没有意思,他的作用就是声明了个double变量,然后接下来的“耗时"操作都invoke到主线程去做了。不还是相当于没有起新线程吗?我觉得你应该把invoke操作移到funCalc里面,当需要更新UI的时候再Invoke。 另外invoke和begininvoke的区别就是一个同步一个异步,当你在子线程调用invoke时候,如果invoke耗时很长,子线程会阻塞在这里,等待invoke执行完再继续。当调用begininvoke,即使begininvoke耗时很长,子线程也会继续向下执行,不等待。
谢谢,很详细,我0楼的代码只是问问题,真正的代码在13楼。 如果用BeginInvoke,必须要配套调用EndInvoke吗?我感觉BeginInvoke线程之间协调比较不好控制。[/quote] 我觉得如果你需要begininvoke执行完后的返回值的话,可以调用下endinvoke,否则就不用配套(我是没怎么配套过)。 begininvoke线程协调间确实不好控制,先begininvoke的不一定先执行。如果对操作的同步问题要求比较严格的话,就用尽量invoke吧,子线程能做的都让子线程做了,这样主线程也没什么压力。 这是我的建议,坐等大牛补充回答。
ooolinux 2017-11-13
  • 打赏
  • 举报
回复
引用 27 楼 qq_17486399 的回复:
你在其他线程里面对界面上的控件进行了操作,就需要使用委托,不然会出现错误,因为其他线程是不能直接操作UI线程的
对,我也碰到过。
加载更多回复(18)

110,499

社区成员

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

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

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