当从后台线程调用System.Web.UI.Control.RenderControl时失败

本文关键字:Control UI RenderControl 失败 Web System 后台 线程 调用 | 更新日期: 2023-09-27 17:51:02

我需要在后台线程中呈现控件,并将输出发送到邮件中。下面这段代码在后台线程中运行:

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(sendmail), new Object());
public void sendmail(object o)
{
    UserControl cntrl = new Page().LoadControl("~/mycontrol.ascx") as UserControl;
    StringWriter stringwriter = new StringWriter();
    Html32TextWriter htmlwriter = new Html32TextWriter(stringwriter);
    cntrl.RenderControl(htmlwriter);
    SendEmailUsingNetMail(stringwriter);
}
At runtime I am getting this exception
System.NullReferenceException: Object reference NOT SET TO an instance of an object.
AT System.Web.UI.HtmlControls.HtmlForm.GetActionAttribute()
AT System.Web.UI.HtmlControls.HtmlForm.RenderAttributes(HtmlTextWriter writer)
AT System.Web.UI.HtmlControls.HtmlControl.RenderBeginTag(HtmlTextWriter writer)
AT System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer)
AT System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter output)
AT System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
AT System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
AT System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer)
AT System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
AT System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
AT System.Web.UI.Control.Render(HtmlTextWriter writer)
AT System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
AT System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
AT System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
AT RedBus.RBMail.sendmail(object o)

同样的代码当从asp.net请求线程运行时工作完全正常。有可能让这个东西在后台线程本身工作吗?如果是,怎么做?

谢谢,普拉丹

当从后台线程调用System.Web.UI.Control.RenderControl时失败

添加一个表单到你的页面:

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(sendmail), new Object());
public void sendmail(object o)
{
    System.Web.UI.Page() pageHolder = new System.Web.UI.Page() 
              {AppRelativeTemplateSourceDirectory = HttpRuntime.AppDomainAppVirtualPath };
    System.Web.UI.HtmlControls.HtmlForm form = new System.Web.UI.HtmlControls.HtmlForm();
    UserControl cntrl = new Page().LoadControl("~/mycontrol.ascx") as UserControl;
    form.Controls.Add(cntrl );
    pageHolder.Controls.Add(form);
    StringWriter stringwriter = new StringWriter();
    HttpContext.Current.Server.Execute(pageHolder, stringwriter, false);
    SendEmailUsingNetMail(stringwriter);
}

另外,我还写了一个叫做ucajax的开源项目来做这件事,这个库是用来与web服务一起使用的,但是你没有理由不能直接调用这些方法来呈现控件。