首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ASP.NET MVC2是否从jQuery调用AsyncController方法?

ASP.NET MVC2是否从jQuery调用AsyncController方法?
EN

Stack Overflow用户
提问于 2011-02-20 06:27:03
回答 1查看 2.6K关注 0票数 2

我正在尝试学习如何在MVC2中使用AsyncController,但是几乎没有文档/教程。我正在寻找一个普通的控制器方法,有一个非常慢的输出到第三方服务,并将其转换为异步方法。

原始的控制器方法:

代码语言:javascript
复制
public JsonResult SaveSalesInvoice(SalesInvoice invoice)
{
    SaveInvoiceToDatabase(invoice); // this is very quick 
    ExportTo3rdParty(invoice); // this is very slow and should be async
}

所以我创建了一个继承自AsyncController的新控制器:

代码语言:javascript
复制
public class BackgroundController : AsyncController
{
    public void ExportAysnc(int id)
    {
        SalesInvoice invoice = _salesService.GetById(id);
        ExportTo3rdParty(invoice);
    }

    public void ExportCompleted(int id)
    {
         // I dont care about the return value right now, 
         // because the ExportTo3rdParty() method
         // logs the result to a table
    }

    public void Hello(int id)
    {            
    }
}

然后从jQuery调用Export方法:

代码语言:javascript
复制
function Export() {
    $.post("Background/Export", { id: $("#Id").val() }, function (data) {
    // nothing to do yet
    });
}

但结果是404 not found (404未找到)错误(未找到背景/导出)。如果我尝试调用Background/Hello或Background/ExportAysnc,则会找到它们。

我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-02-20 16:59:19

确实有两个用例

  1. 你只关心冗长操作的结果
  2. 你不关心结果(点火后忘记)

让我们从第一个案例开始:

代码语言:javascript
复制
public class BackgroundController : AsyncController
{
    public void ExportAysnc(int id)
    {
        AsyncManager.OutstandingOperations.Increment();

        Task.Factory.StartNew(() => DoLengthyOperation(id));

        // Remark: if you don't use .NET 4.0 and the TPL 
        // you could manually start a new thread to do the job
    }

    public ActionResult ExportCompleted(SomeResult result)
    {
        return Json(result, JsonRequestBehavior.AllowGet);
    }

    private void DoLengthyOperation(int id)
    {
        // TODO: Make sure you handle exceptions here
        // and ensure that you always call the AsyncManager.OutstandingOperations.Decrement()
        // method at the end
        SalesInvoice invoice = _salesService.GetById(id);
        AsyncManager.Parameters["result"] = ExportTo3rdParty(invoice);
        AsyncManager.OutstandingOperations.Decrement();
    }
}

现在您可以像这样调用它:

代码语言:javascript
复制
$.getJSON(
    '<%= Url.Action("Export", "Background") %>', 
    { id: $("#Id").val() }, 
    function (data) {
        // do something with the results
    }
);

现在,因为您已经提到了web服务调用,这意味着当您生成web服务的客户端代理时,您有机会发出异步方法(XXXCompleted和XXXAsync):

代码语言:javascript
复制
public class BackgroundController : AsyncController
{
    public void ExportAysnc(int id)
    {
        AsyncManager.OutstandingOperations.Increment();
        // that's the web service client proxy that should
        // contain the async versions of the methods
        var someService = new SomeService();
        someService.ExportTo3rdPartyCompleted += (sender, e) =>
        {
            // TODO: Make sure you handle exceptions here
            // and ensure that you always call the AsyncManager.OutstandingOperations.Decrement()
            // method at the end

            AsyncManager.Parameters["result"] = e.Value;
            AsyncManager.OutstandingOperations.Decrement();
        };
        var invoice = _salesService.GetById(id);
        someService.ExportTo3rdPartyAsync(invoice);
    }

    public ActionResult ExportCompleted(SomeResult result)
    {
        return Json(result, JsonRequestBehavior.AllowGet);
    }
}

这是异步控制器的最佳用途,因为它依赖于I/O完成端口,并且在执行冗长的操作期间不会独占服务器上的任何线程。

第二种情况更简单(实际上不需要异步控制器):

代码语言:javascript
复制
public class BackgroundController : Controller
{
    public ActionResult Export(int id)
    {
        // Fire and forget some lengthy operation
        Task.Factory.StartNew(() => DoLengthyOperation(id));
        // return immediately
        return Json(new { success = true }, JsonRequestBehavior.AllowGet);
    }
}

这是一个关于异步控制器的nice article on MSDN

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5053942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档