我正在编写一个后台工作程序,在线程执行完毕后调用“WorkerFinished”事件。但问题是,我显然无法更新此事件处理程序中的任何UI元素。我需要在线程完成后在主ASP页面中启用一些按钮。
所以,我知道我不能这样直截了当地做到这一点,但我对如何解决这个问题没有丝毫的线索。
以下是相关代码:
public void Start(Dictionary<string, object> args)
{
m_thread = new Thread(() =>
{
m_progress = 0;
DoWork.Invoke(ref m_progress, ref m_result, args);
m_progress= 100;
m_isDone= true;
if( FinishedWork != null )
FinishedWork.Invoke(ref m_result, args); // Here goes
});
m_thread .Name = m_name;
m_thread .IsBackground = true;
m_thread .Start();
}
因此,我在ASP页面上订阅 FinishedWork 事件,我需要再次启用“开始”按钮。
那么,有没有办法让我确保在UI线程上发生这种调用?
谢谢,Oyvind。
答案 0 :(得分:1)
你做不到。当您完成后台任务时,已经发送了对客户端的响应。没了。如果您尝试向客户端发送任何不响应特定请求的信息,或者对于已收到响应的请求,则他们的防火墙肯定会阻止该传输。这与标准网络模型完全相反。客户端发出请求,服务器发送响应,就是这样。
该模型不是为客户端和服务器之间的双向通信而设计的,服务器可以随时将数据发送到客户端。
做支持这种双向沟通的模型存在,但并非所有客户都支持它。
另一种选择是让客户端不断地轮询服务器(大概是异步地),不断询问它,“你还没完成?”,“你完成了吗?”,“你还没完成?”这里的一般模型是异步任务将以未来请求(即数据库,会话等)可访问的全局状态的形式存储与其进度有关的一些信息,并且来自客户端的频繁轮询请求将查看该状态。可以看到此模型的一个示例here。请注意,这在网络上非常耗费资源,需要不断轮询服务器以进行更新,因此请谨慎使用此模式。