想问一个关于多线程的问题

沫林 2019-04-23 10:33:28

这是两条线程
YjMenthod();这个方法会执行一个很卡的任务,为了防止界面卡死,我把它放到一个叫thr的子线程里了,然后为了优化用户体验,我写了一个动画,这个ucld是那个控件的实例化,但是为什么thr这个线程卡死的时候我放在th线程里的ucld动画也不执行了呢,等yjmenthod执行完后,动画才开始转
...全文
841 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
luj_1768 2019-04-26
  • 打赏
  • 举报
回复
想法有些奇特。可能需要专用设备才能运行。不如自己在家多做些测试,再来和大家交流。
cpongo3 2019-04-25
  • 打赏
  • 举报
回复
你在nock
cpongo3 2019-04-25
  • 打赏
  • 举报
回复
就是想说为啥你这样做
love氟利昂 2019-04-24
  • 打赏
  • 举报
回复
引用 15 楼 沫林 的回复:
[quote=引用 12 楼 jflyseven 的回复:]
[quote=引用 10 楼 沫林 的回复:]
[quote=引用 8 楼 jflyseven的回复:]猜测YjMenthod方法中也存在委托到主线程的代码。
因为第二个异步委托也是委托在主线程上,如果YjMethod方法首先触发了委托会阻塞掉第二个委托。
原因:无论同步或者异步委托,如果都是委托在同一个线程上,实际执行时是同步执行的。

确实有一个begininvok,但是我要访问主线程是控件和变量啊[/quote]
我指的主线程就是UI线程,我不太清楚thr线程中YjMethod方法、ucld控件和UI线程之间做了什么操作,因此我只能猜测可能是委托导致的。如果ucld控件是类似对YjMethod方法指示的进度条或者跑马灯之类的东西的话,如果你找不到其它方法解决的方法的话,你大可以把所有的操作对它的操作放在YjMethod中尝试一下。方法仅供参考。[/quote]
ucld是一个用户控件的实例, 这个控件里面写的是动画,yjmethod会调用两个主线程中的变量,然后把从数据库中查出来的东西保存到这两个变量里,最后调用两个方法这变量里的东西导出为word和excel,这两个导出word和excel方法是借助了两个类完成的,因为是公共用的类,所以不可以把这两个类也写到工作线程里。[/quote]
我的意思是如果你找不到其它方法解决的方法的话,你大可以把所有对ucld的操作放在YjMethod中尝试一下。不是让你把所有的代码写在同一个方法里面,而是把所有涉及与当前界面的UI交互的代码写在同一个线程里面。
杀马特丶蛮牛 2019-04-24
  • 打赏
  • 举报
回复
看看这个。
private void button1_Click(object sender, EventArgs e)
{
Thread th = new Thread(new ThreadStart(() =>
{
//Thread.Sleep(3000);//放这里不阻塞主界面,只阻塞th
label1.BeginInvoke((MethodInvoker)delegate ()
{
//sleep放这里界面卡死,label2不会先变成2,而是等label1改了之后同时变过来,放在这里是阻塞主线程
//你的很卡的任务,需要放在外面执行,显示的时候才放到begininvoke里面
Thread.Sleep(3000);
this.label1.Text = "1";
});
}));
th.Start();

Thread th1 = new Thread(new ThreadStart(() =>
{
Thread.Sleep(1000);
label2.BeginInvoke((MethodInvoker)delegate ()
{
this.label2.Text = "2";
});
}));
th1.Start();

}
沫林 2019-04-24
  • 打赏
  • 举报
回复
引用 12 楼 jflyseven 的回复:
[quote=引用 10 楼 沫林 的回复:]
[quote=引用 8 楼 jflyseven的回复:]猜测YjMenthod方法中也存在委托到主线程的代码。
因为第二个异步委托也是委托在主线程上,如果YjMethod方法首先触发了委托会阻塞掉第二个委托。
原因:无论同步或者异步委托,如果都是委托在同一个线程上,实际执行时是同步执行的。

确实有一个begininvok,但是我要访问主线程是控件和变量啊[/quote]
我指的主线程就是UI线程,我不太清楚thr线程中YjMethod方法、ucld控件和UI线程之间做了什么操作,因此我只能猜测可能是委托导致的。如果ucld控件是类似对YjMethod方法指示的进度条或者跑马灯之类的东西的话,如果你找不到其它方法解决的方法的话,你大可以把所有的操作对它的操作放在YjMethod中尝试一下。方法仅供参考。[/quote]
ucld是一个用户控件的实例, 这个控件里面写的是动画,yjmethod会调用两个主线程中的变量,然后把从数据库中查出来的东西保存到这两个变量里,最后调用两个方法这变量里的东西导出为word和excel,这两个导出word和excel方法是借助了两个类完成的,因为是公共用的类,所以不可以把这两个类也写到工作线程里。
沫林 2019-04-24
  • 打赏
  • 举报
回复
引用 13 楼 STSeven 的回复:
这代码不能看 你是想背后执行一个耗时动作 同时前端加载一个等待动画吧?
grid.Children.Add(ucld);
thr = new Thread(YjMenthod);
thr.Start();
这样就行了 。确保YjMenthod没有阻塞主界面的操作!
如果还不会 了解下BackgroundWorker

整个yjmenthod();都用了一个 this.Dispatcher.BeginInvoke(new Action(delegate{ })) 包起来的,里面调用了两个主线程的变量,然后会查数据库,把值保存到这两个变量里,最后调用另外两个方法,把这两个变量的值导出为word和excel。
STSeven 2019-04-24
  • 打赏
  • 举报
回复
这代码不能看 你是想背后执行一个耗时动作 同时前端加载一个等待动画吧?
grid.Children.Add(ucld);
thr = new Thread(YjMenthod);
thr.Start();
这样就行了 。确保YjMenthod没有阻塞主界面的操作!
如果还不会 了解下BackgroundWorker
love氟利昂 2019-04-24
  • 打赏
  • 举报
回复
引用 10 楼 沫林 的回复:
[quote=引用 8 楼 jflyseven的回复:]猜测YjMenthod方法中也存在委托到主线程的代码。
因为第二个异步委托也是委托在主线程上,如果YjMethod方法首先触发了委托会阻塞掉第二个委托。
原因:无论同步或者异步委托,如果都是委托在同一个线程上,实际执行时是同步执行的。

确实有一个begininvok,但是我要访问主线程是控件和变量啊[/quote]
我指的主线程就是UI线程,我不太清楚thr线程中YjMethod方法、ucld控件和UI线程之间做了什么操作,因此我只能猜测可能是委托导致的。如果ucld控件是类似对YjMethod方法指示的进度条或者跑马灯之类的东西的话,如果你找不到其它方法解决的方法的话,你大可以把所有的操作对它的操作放在YjMethod中尝试一下。方法仅供参考。
沫林 2019-04-24
  • 打赏
  • 举报
回复
引用 6 楼 橘子皮zzz的回复:
感觉你写的有问题啊,delegate里又invoke,不是多此一举么
我知道啊,但是我不是主线程,我看了楼下的回答猜测可能是委托的原因,但是感觉很棘手
沫林 2019-04-24
  • 打赏
  • 举报
回复
引用 8 楼 jflyseven的回复:
猜测YjMenthod方法中也存在委托到主线程的代码。
因为第二个异步委托也是委托在主线程上,如果YjMethod方法首先触发了委托会阻塞掉第二个委托。
原因:无论同步或者异步委托,如果都是委托在同一个线程上,实际执行时是同步执行的。
确实有一个begininvok,但是我要访问主线程是控件和变量啊
沫林 2019-04-24
  • 打赏
  • 举报
回复
引用 2 楼 OrdinaryCoder的回复:
[quote=引用 1 楼 OrdinaryCoder 的回复:]
th线程好像可以去掉,只留下this.Dispatcher.BeginInvoke()里的内容就行 这句是传一个委托到界面线程去工作 你再放一个线程就没有意义了

去掉试一下[/quote] 去掉了,还是不行啊,thr那个线程吧主线程都卡死了
love氟利昂 2019-04-24
  • 打赏
  • 举报
回复
猜测YjMenthod方法中也存在委托到主线程的代码。
因为第二个异步委托也是委托在主线程上,如果YjMethod方法首先触发了委托会阻塞掉第二个委托。
原因:无论同步或者异步委托,如果都是委托在同一个线程上,实际执行时是同步执行的。
沫林 2019-04-24
  • 打赏
  • 举报
回复
引用 3 楼 exception92的回复:
Thread默认为前台线程,Yjmenthod同步执行直到执行完毕。了解一下Thread的IsBackgorund属性。
不是这个的原因,我加过,没用
沫林 2019-04-24
  • 打赏
  • 举报
回复
引用 19 楼 jflyseven的回复:
[quote=引用 14 楼 沫林 的回复:]
[quote=引用 13 楼 STSeven 的回复:]
这代码不能看 你是想背后执行一个耗时动作 同时前端加载一个等待动画吧?
grid.Children.Add(ucld);
thr = new Thread(YjMenthod);
thr.Start();
这样就行了 。确保YjMenthod没有阻塞主界面的操作!
如果还不会 了解下BackgroundWorker

整个yjmenthod();都用了一个 this.Dispatcher.BeginInvoke(new Action(delegate{ })) 包起来的,里面调用了两个主线程的变量,然后会查数据库,把值保存到这两个变量里,最后调用另外两个方法,把这两个变量的值导出为word和excel。[/quote]
噗,之前没看到。你怎么能把YjMethod全部委托到UI线程呢,只需要委托涉及和UI交互的地方呀。犯的错误太低级了,。[/quote] 啊哈哈,还真的是
love氟利昂 2019-04-24
  • 打赏
  • 举报
回复



引用 14 楼 沫林 的回复:
[quote=引用 13 楼 STSeven 的回复:]
这代码不能看 你是想背后执行一个耗时动作 同时前端加载一个等待动画吧?
grid.Children.Add(ucld);
thr = new Thread(YjMenthod);
thr.Start();
这样就行了 。确保YjMenthod没有阻塞主界面的操作!
如果还不会 了解下BackgroundWorker

整个yjmenthod();都用了一个 this.Dispatcher.BeginInvoke(new Action(delegate{ })) 包起来的,里面调用了两个主线程的变量,然后会查数据库,把值保存到这两个变量里,最后调用另外两个方法,把这两个变量的值导出为word和excel。[/quote]
噗,之前没看到。你怎么能把YjMethod全部委托到UI线程呢,只需要委托涉及和UI交互的地方呀。犯的错误太低级了,
STSeven 2019-04-24
  • 打赏
  • 举报
回复
引用 14 楼 沫林 的回复:
[quote=引用 13 楼 STSeven 的回复:]
这代码不能看 你是想背后执行一个耗时动作 同时前端加载一个等待动画吧?
grid.Children.Add(ucld);
thr = new Thread(YjMenthod);
thr.Start();
这样就行了 。确保YjMenthod没有阻塞主界面的操作!
如果还不会 了解下BackgroundWorker

整个yjmenthod();都用了一个 this.Dispatcher.BeginInvoke(new Action(delegate{ })) 包起来的,里面调用了两个主线程的变量,然后会查数据库,把值保存到这两个变量里,最后调用另外两个方法,把这两个变量的值导出为word和excel。[/quote]

把yjmenthod()里面的this.Dispatcher.BeginInvoke(new Action(delegate{ })) 去掉 不要包起来!
exception92 2019-04-23
  • 打赏
  • 举报
回复
Thread默认为前台线程,Yjmenthod同步执行直到执行完毕。了解一下Thread的IsBackgorund属性。
OrdinaryCoder 2019-04-23
  • 打赏
  • 举报
回复
引用 1 楼 OrdinaryCoder 的回复:
th线程好像可以去掉,只留下this.Dispatcher.BeginInvoke()里的内容就行 这句是传一个委托到界面线程去工作 你再放一个线程就没有意义了

去掉试一下
OrdinaryCoder 2019-04-23
  • 打赏
  • 举报
回复
th线程好像可以去掉,只留下this.Dispatcher.BeginInvoke()里的内容就行 这句是传一个委托到界面线程去工作 你再放一个线程就没有意义了
加载更多回复(3)

110,499

社区成员

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

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

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