gpt4 book ai didi

c# - ASP.NET MVC2 从 jQuery 调用 AsyncController 方法?

转载 作者:行者123 更新时间:2023-11-30 19:48:46 37 4
gpt4 key购买 nike

我正在尝试学习如何在 MVC2 中使用 AsyncController,但那里的文档/教程很少。我希望采用一种普通的 Controller 方法,该方法导出到第 3 方服务的速度非常慢,并将其转换为异步方法。

原来的 Controller 方法:

public JsonResult SaveSalesInvoice(SalesInvoice invoice)
{
SaveInvoiceToDatabase(invoice); // this is very quick
ExportTo3rdParty(invoice); // this is very slow and should be async
}

所以我创建了一个继承自 AsyncController 的新 Controller :

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 方法:

function Export() {
$.post("Background/Export", { id: $("#Id").val() }, function (data) {
// nothing to do yet
});
}

但结果是 404 未找到错误(未找到后台/导出)。如果我尝试调用 Background/Hello 或 Background/ExportAysnc,就会找到它们。

我做错了什么?

最佳答案

确实有两个用例

  1. 您关心长时间操作的结果
  2. 你不关心结果(即发即弃)

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

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();
}
}

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

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

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

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);
}
}

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


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

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在异步 Controller 上。

关于c# - ASP.NET MVC2 从 jQuery 调用 AsyncController 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5053942/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com