asp.net 多线程问题,页面开了一个工作线程,工作线程向页面线程汇报进度,然后页面线程向client输出当前信息, 如何实现?

hjon 2009-03-20 11:01:49
大家有没有这样的例子,提供参考一下,
或者有没有比较好的想法来实现。

我尝试了一个方法但是失败了,就是传一个delegate给工作线程,在delegate事件里面向client输入当前进度,但是出了问题,我估计是工作线程不能直接修改页面元素,在winform里面有个Invoke方法可以解决这个问题,但是在asp.net里面好像没有Invoke这样的异步调味用方法.


...全文
880 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
paradise80 2011-10-14
  • 打赏
  • 举报
回复
先指出我对你的solution的一些疑惑:
1. 你用while轮询线程岂不是丧失了线程的意义,不是等于把逻辑直接放到主线程里了吗.再说这样的轮询势必会导致cpu 高占用. 即使你在while中用了休眠,同样感觉是为了多线程而多线程.
2. 很好奇你是怎么在背景线程中向浏览器报告状态的. 要报告状态意味着要返回response, 这样会结束整个request的处理,中止所有线程.相当于一个reponse.end, 不管什么调用它的主线程还是while循环,通通中止.(如果不幸还包在一个try catch中,直接导致异常终止的服务器端异常)

我的理解是这样:
首先, 要把winform的逻辑搬到web上.先划分清楚模块.
winform里面异步调用的两端:UI线程(主线程)和背景线程,在web里面对应的应该是浏览器和服务器. 你要一个进度条显示进程, 其实要做的是在浏览器端用Ajax询问状态. 每一次询问都是一个Request, 每次服务器端都会走一个page life cycle.
所以要把整个耗时工作逻辑和状态放到一个更长生命周期的服务器对象中执行,例如Global,也就是ApplicationContext里面. 但是asp.net目前据我了解并不保证每个reuqest都会引用同一个Application 对象. (如果用到cluster情况更加糟糕). 所以如果真的需要用背景线程,最好就把状态放到数据库中,每次ajax过来轮询的时候从数据库读.

我没有过类似的实际经验,哪怕是上传文件这样的需要状态条的也没做过. 不太清楚那个是怎么做的. 很希望探讨一下这种有状态条的做法.

看懂了的而且有经验的麻烦指点一下!!!!
enlarge 2011-06-25
  • 打赏
  • 举报
回复
愣是没有看懂
qcjxberin 2010-04-16
  • 打赏
  • 举报
回复
学习下。
cedar_bj 2010-03-18
  • 打赏
  • 举报
回复
采用什么样子的状态对象呀?
Fredjiang_sh 2010-02-07
  • 打赏
  • 举报
回复
回答的很好,我也正在找这种问的解决办法。谢了。
xmdefault 2009-04-10
  • 打赏
  • 举报
回复
同样的问题,不一样的解决
hjon 2009-03-24
  • 打赏
  • 举报
回复
问题解决了,谢谢几位的帮助。关键的几点:

1.就像是[jzywh]所讲的那样,应该是主线程向工作线程询问,我采取的方法是保存一个状态对象,工作线程写,主线程读。
2.像[sp1234]所讲的那样,搞清楚ASP.NET的life time很重要。我这个问题的解决方法是,让主线程在一个while(true)里面循环,询问工作线程当前状态,如果完成了就退出,此时才会向client response.
3.在while(true)循环时,工作线程会向client UI输入一个进度报告,这个进度条弄了好几天才弄出来,用了一个Ajax ModalPopup控件,和一个别人写的进度条控件。

jzywh 2009-03-20
  • 打赏
  • 举报
回复
应该是页面线程向工作线程询问进度
zzc205 2009-03-20
  • 打赏
  • 举报
回复
web控件没有Invoke没关系。可以试下如下方法:
1、在界面线程定义操作界面元素的相关方法。
2、定义委托并传递给工作线程。
3、在工作线程里调用 委托.Invoke()
hjon 2009-03-20
  • 打赏
  • 举报
回复
方法都写好了。
zzxap 2009-03-20
  • 打赏
  • 举报
回复
你先把那两个方法写好。

再把方法放进线程里运行。
hjon 2009-03-20
  • 打赏
  • 举报
回复
楼上说的很在点子上,我是asp.net新手,以前只了解一点asp.net page life cycle,view state这方面的东西,现在正在深入学习。
我现在要做的项目是把在winform下实现的功能再用asp.net来实现出来。

我说的那个问题有没有可以解决的办法?

比如把HttpContext或者Response, Request这些对象保存起来,给工作线程用,
工作线程里面调用Response.Redirect(Request.Url.ToString())等方法让页面重新加载.
  • 打赏
  • 举报
回复
在asp.net上开发交互程序,要先了解asp.net的界面机制,例如Page控件以及所有其它控件的机制。不要随便套用跟表现层框架编程无关的概念。asp.net尽管界面和交互效果远远比WinForm、Silverlight差很多,开发起来实际上却非常麻烦,不是真的不需要技术门槛的。
  • 打赏
  • 举报
回复
你了解过 Page 对象的生命周期吗?你了解了向客户端输出html是在生命周期的哪一个环节吗?

当 Page 处理完一个客户端请求,它就被释放了,也就是说你的所谓工作线程的宿主被释放了。实际上就算不释放,也已经过了向客户端输出html的那个环节了,你再如何“修改页面元素”也是直接丢到下水道里而不会被输出到用户那里去了。
hjon 2009-03-20
  • 打赏
  • 举报
回复
我现在还发现了另外一个问题,在工作线程里面访问HttpContext.Current.Session会出错,
好像是访问这些对象的时候它们已经不存在了,因为这些对象只在一次请求里面有效,工作线程访问的时候它们都已经无效了。
hjon 2009-03-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zzc205 的回复:]
web控件没有Invoke没关系。可以试下如下方法:
1、在界面线程定义操作界面元素的相关方法。
2、定义委托并传递给工作线程。
3、在工作线程里调用 委托.Invoke()
[/Quote]

通过这种方法好像也达不到异步调用的效果,就像在winform中的那样。
hjon 2009-03-20
  • 打赏
  • 举报
回复
如果采用询问,是不是可以这样做:
1.两个线程同步一个表示当前状态的对象,工作线程写,页面线程访问。
2.页面线程添加一个timer

62,050

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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