在单独的线程中执行操作以解锁 UI

2024-02-04

我有一个用于生成报告的表格。我们正在使用RDLC报告并且报告被加载到aspx page.

所以这是代码Form,表单目标设置为_blank,并在新选项卡中打开。

@using (Html.BeginForm("AssetReports", "AssetReports", FormMethod.Post, new { target = "_blank" }))
{
    <div class="row mt-15">
        <div class="col-md-12 text-center">
            <input type="submit" class="btn btn-primary" value="Show Report" />
        </div>
    </div>
}

这是重定向到报告 aspx 页面的控制器操作,在该页面中处理并显示报告。

[HttpPost]
public void AssetReports(AssetReportsDTO model, AssetReportParametersDTO reportParameters)
{
    SessionHandler.AssetReport = model;
    SessionHandler.AssetReportParameters = reportParameters;

    switch (model.SelectedReportType)
    {
        case AssetReportTypesEnum.ExcessiveIdleReport:
            Response.Redirect("~/Reports/AssetReports/ExcessiveIdleReport/ExcessiveIdleReport.aspx");
            break;
    }
}

在某些情况下,生成报告需要 3.4 分钟。在此期间,UI 被阻止,

我们希望报告在单独的线程上生成,以便用户可以在生成报告时使用 UI。

MVC C# 中有没有办法在单独的线程中执行此操作?

我尝试使用以下内容,但上下文和会话是NULL

Task.Factory.StartNew(() =>
{
    switch (model.SelectedReportType)
    {
        case AssetReportTypesEnum.ExcessiveIdleReport:
            Response.Redirect("~/Reports/AssetReports/ExcessiveIdleReport/ExcessiveIdleReport.aspx");
            break;
    }
});

并且:

new Thread(() =>
{
    switch (model.SelectedReportType)
    {
        case AssetReportTypesEnum.ExcessiveIdleReport:
            Response.Redirect("~/Reports/AssetReports/ExcessiveIdleReport/ExcessiveIdleReport.aspx");
            break;
    }
}).Start();

EDIT

用于生成报告的代码 - 此代码需要 3 到 4 分钟ExcessiveIdleReport.aspx

public partial class ExcessiveIdleReport1 : Page
    {
        private IReportsProvider _reportsProvider;

        protected void Page_Load(object sender, EventArgs e)
        {
            _reportsProvider = new ReportsProvider();
            if (!IsPostBack)
            {
                try
                {
                    var reportDetails = SessionHandler.AssetReport;
                    var reportParams = SessionHandler.AssetReportParameters;



                    var sPath = Server.MapPath("../ExcessiveIdleReport/ExcessiveIdleReport.rdlc");
                    var dsExcessiveReport =
                        _reportsProvider.GetExcessiveIdleReport(reportDetails.CompanyId, reportDetails.AssetId, reportDetails.StartDate,
                                                                reportDetails.EndDate, reportParams.SelectedIdleTime * 60);

                    ExcessiveIdleReportViewer.ProcessingMode = ProcessingMode.Local;
                    ExcessiveIdleReportViewer.LocalReport.EnableHyperlinks = true;
                    ExcessiveIdleReportViewer.HyperlinkTarget = "_blank";
                    ExcessiveIdleReportViewer.LocalReport.DataSources.Add(new ReportDataSource("ExcessiveIdleReport", dsExcessiveReport.Tables[0]));
                    ExcessiveIdleReportViewer.LocalReport.DataSources.Add(new ReportDataSource("ReportHeaderDetails", dsExcessiveReport.Tables[1]));
                    ExcessiveIdleReportViewer.LocalReport.DataSources.Add(new ReportDataSource("ReportSummary", dsExcessiveReport.Tables[2]));
                    ExcessiveIdleReportViewer.LocalReport.ReportPath = sPath;

                    ExcessiveIdleReportViewer.LocalReport.EnableExternalImages = true;
                    ExcessiveIdleReportViewer.LocalReport.SetParameters(param);

                    ExcessiveIdleReportViewer.LocalReport.Refresh();

                }
                catch (Exception ex)
                {
                    ErrorDiv.InnerText = string.Format("An error occured while generating the ExcessiveIdleReport, Please contact Support with following Message: [{0}] - [{1}]", ex.Message, ex.StackTrace);
                    ReportContentDiv.Visible = false;
                    ErrorDiv.Visible = true;
                }
            }
        }
    }

我也尝试过使用Ajax.BeginForm

 @using (Ajax.BeginForm("AssetReports", "AssetReports", new AjaxOptions() { HttpMethod = "POST", OnSuccess = "OpenReport"}, new { target = "_blank" }))
            {

            <div class="row mt-15">
                <div class="col-md-12 text-center">
                    <input type="submit" class="btn btn-primary" value="Show Report" />
                </div>
            </div>
}

JS:

function OpenReport(response) {
    var popup = window.open("about:blank", "_blank"); // the about:blank is to please Chrome, and _blank to please Firefox
    popup.location = '/TBReports/AssetReports/ExcessiveIdleReport/ExcessiveIdleReport.aspx';
}

我使用 Ajax 加载所有其他页面:

以下是执行操作的资产报告页面“显示报告”按钮的图像:

但是一旦单击此按钮,其他 UI 元素就会被阻止。例如我无法加载视图Group Reports直到生成报告。


ASP.NET MVC 倾向于序列化同一会话的请求,除非您指定该会话是只读的。

在微软的这篇文章中,https://msdn.microsoft.com/en-us/library/ms178581.aspx https://msdn.microsoft.com/en-us/library/ms178581.aspx, 它指出:

并发请求和会话状态

对 ASP.NET 会话状态的访问是每个会话独占的,这意味着 如果两个不同的用户并发请求,则访问每个 同时授予单独的会话。但是,如果两个并发 对同一会话发出请求(通过使用相同的 SessionID value),第一个请求获得对会话的独占访问权 信息。第二个请求仅在第一个请求之后执行 完成了。 (如果独占,第二个会话也可以获得访问权限 由于第一个请求超出了限制,信息上的锁定被释放 锁定超时。)如果@Page中的EnableSessionState值 指令设置为ReadOnly,请求只读会话 信息不会导致会话数据上的独占锁定。 但是,对会话数据的只读请求可能仍需要等待 用于清除会话数据的读写请求设置的锁。

您可能想要考虑将会话状态设置为只读或使用更明智的技术,例如 Node.js。 (最后一点只是开玩笑……)

请参阅约翰·卡尔文纳 (John Culviner) 的文章:http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/ http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/,他说:

MVC 3 的解决方案

幸运的是,微软已经提供了 ENUM 值 System.Web.SessionState.SessionStateBehavior 允许我们放弃 独占会话锁的权利。主要是价值观:

ReadOnly – 不阻止其他请求,因为该请求不能 更新会话已禁用 – 无法阻止,这是您的最佳选择 StateServer 和 SQL 模式下的性能,因为不需要序列化 发生。请记住,所有会话都是序列化和反序列化的 每次每个用户。不仅仅是您正在访问的特定密钥。

在您的 MVC 3 属性中添加一个新的属性,其中包含您想要的枚举值 控制器类如下:

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class TestController : Controller
{
    public ActionResult Index()
    {
        System.Threading.Thread.Sleep(10000);
        return new EmptyResult();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在单独的线程中执行操作以解锁 UI 的相关文章

随机推荐

  • Xcode 构建完美失败——找不到 COpenSSL

    代码 8 0 Swift 工具链 3 0 版本 完美的 Package url https github com PerfectlySoft Perfect HTTPServer git majorVersion 2 minor 0 跑起来
  • PID和TID的区别

    PID和TID有什么区别 标准答案是 PID 用于进程 而 TID 用于线程 然而 我发现有些命令可以互换使用它们 例如 htop有一个 PID 列 其中显示同一进程的线程的 PID 具有不同的值 那么PID什么时候代表线程或进程呢 这很复
  • 如何检测IE6,并显示警报?

    我试图在使用 IE6 的用户使用我的网站时显示警报 我想这样的事情会起作用 我会对此进行测试 但我没有可以使用 ATM 的 Windows 盒子 这是正确的方法吗 是的 这有效 当然 你可以使用像这样的东西 http code google
  • 如何解析 XML 并获取特定节点属性的实例?

    我在 XML 中有很多行 并且正在尝试获取特定节点属性的实例
  • 如何使 Eclipse Formatter 不破坏注释掉的代码?

    我的很多同事喜欢留下注释掉的代码 以及如何使 Eclipse Formatter 不破坏该代码的格式 现在它会生成一个大斑点或块 附 我知道我可以以某种方式配置格式化程序以忽略该代码 我做过一次 但我不记得如何做 在 Eclipse 格式化
  • 使用 Python 通过 Mailgun 提交变量时出错

    我正在尝试使用 Python 通过 Mailgun 发送邮件 在这种情况下 我正在尝试将变量推到旁边 我的代码如下 requests post MailGun URL auth api api key data from From Mail
  • 使用 Cx_freeze 或 Py2Exe 打包 Scrapy 应用程序

    我正在尝试打包一个网络抓取脚本 使用 scrapy 构建 作为独立应用程序运行 供我的老板使用 我使用 Tkinter 构建了一个小型桌面 GUI 它通过 os system 调用来调用我的 Scrapy 蜘蛛 我当前的构建实现 使用 cx
  • VHDL 中的 BRAM_INIT

    我正在模拟基于处理器的设计 其中程序存储器内容保存在 BRAM 中 我正在使用 VHDL 推断 BRAM 实现程序存储器 我试图避免使用 CoreGen 因为我想保持设计的可移植性 最终该设计将进入 FPGA 我想看看是否有一种方法可以使用
  • 如何集成Pygame和PyQt4?

    我正在使用 python 2 7 和 Ubuntu 14 04 我正在尝试做this http www pygame org docs ref display html pygame display init为了让我的 pygame 窗口位
  • 从源文件中删除所有注释(单行/多行)和空行[重复]

    这个问题在这里已经有答案了 如何从 C 源文件中删除所有注释和空行 请记住 可能存在嵌套注释 一些例子 string text not a comment a comment multiline comment string newText
  • 在脸部周围绘制精美的矩形

    我使用以下代码来检测脸部并在脸部顶部绘制矩形 while True get video frame ret img cap read input img cv2 cvtColor img cv2 COLOR BGR2RGB img h im
  • MvvmCross - 如何将 UIView.Layer.AnyProperty (Xamarin.iOS) 绑定到视图模型上的属性?

    我在视图模型上有一个名为 BorderColor 的字符串类型的属性 我尝试将其绑定到 UIView Layer BorderColor 这是绑定语法 set Bind this MyUIView For Layer BorderColor
  • Xcode 源自动格式化

    As a C developer I have become highly dependent on the automatic formatting in Visual Studio 2008 Specifically I will us
  • 从 mysql_connect() 获取 PHP PDO 连接?

    我有一个旧版 PHP MySQL 应用程序调用 mysql connect 大量现有的下游代码使得mysql query 使用此连接直接或通过包装器进行调用 对于我在应用程序上开发的新代码 我想开始使用 PDO 如果我使用相同的主机 用户
  • “DataLoader”对象不支持索引

    我已经通过此 pytorch api 通过设置 download True 下载了 ImageNet 数据集 但我无法迭代数据加载器 错误显示 DataLoader 对象不支持索引 trainset torch utils data Dat
  • 调用mapViewDidFailLoadingMap委托方法时出现错误== 0

    在我的视图控制器中 我创建了一个 MKMapView 对象 我将委托设置为 self 并在 ViewController 中实现 void mapViewDidFailLoadingMap MKMapView mapView withErr
  • Spring data - 根据先前的插入插入数据

    我需要将数据保存到两个表中 一个实体和一个关联表 我只是用以下命令保存我的实体save 我的实体存储库中的方法 然后 为了性能 我需要将行插入到关联表中原生sql 这些行有我之前保存的实体的引用 问题来了 我得到一个完整性约束异常关于外键
  • jQuery - 窗口焦点、模糊事件未触发 - 适用于 Firefox 和 Chrome

    简而言之 我编写了一个简单的聊天应用程序供我和我的朋友使用 当运行应用程序的窗口没有焦点 最小化或位于其他窗口后面 并且出现消息时 我想更改窗口标题栏以充当警报 就像 Google 的聊天应用程序在 GMail 中所做的那样 在 Firef
  • 如何在 Phpunit 的静态提供程序中创建测试双打?

    Phpunit 10 已弃用非静态测试提供程序 这使得在提供者内部创建测试替身成为问题 因为像这样的方法createMock or createStub 不是静态的 这是一个演示该问题的假测试 public function provide
  • 在单独的线程中执行操作以解锁 UI

    我有一个用于生成报告的表格 我们正在使用RDLC报告并且报告被加载到aspx page 所以这是代码Form 表单目标设置为 blank 并在新选项卡中打开 using Html BeginForm AssetReports AssetRe