2

语境

我有这个函数可以在一个表和几个远程 IIS 之间同步一个站点列表:

namespace Dashboard.Controllers
{
    public class SiteController : Controller
    {
        public ActionResult Synchronize()
        {
            SiteModel.synchronizeDBWithIIS();

            return Content("Cool.");
        }
    }
}

我想在仪表板启动和运行时异步调用此函数。

问题

  • 你建议我做一个$.get()(jQuery)还是使用AsyncResult(ASP.NET)?

  • 可以用Application_start()Global.asax吗?

  • 此外,我可以改进这个控制器以加快同步速度吗?

4

2 回答 2

2

以上都不是。这是您根本不应该在 ASP.NET 应用程序中做的事情。您可以阅读以下有关此危险的文章: http: //haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

这应该在单独的应用程序中完成。例如,您可以使用 Windows 任务调度程序定期运行此应用程序,它会负责执行此冗长的操作。

在 ASP.NET 应用程序中,没有什么比长时间阻塞工作线程更糟糕的了。在 ASP.NET 应用程序中实现这一点的唯一可能可接受的解决方案是使用 I/O 完成端口。然后你可以使用AsyncController。但据我所知,您SiteModel.synchronizeDBWithIIS();是一种阻塞方法,因此无法完成。

但是,如果您SiteModel提供了一个异步 API 来执行 I/O 密集型任务(不是 CPU 密集型任务),那么它的实现方式如下:

public class SiteController : AsyncController
{
    public void SynchronizeAsync()
    {
        AsyncManager.OutstandingOperations.Increment();

        SiteModel.GetHeadlinesCompleted += (sender, e) =>
        {
            AsyncManager.OutstandingOperations.Decrement();
        };

        SiteModel.synchronizeDBWithIISAsync();
    }

    public ActionResult SynchronizeCompleted()
    {
        return Content("Cool.");
    }
}

一旦你这样做了,无论你是使用 AJAX 调用还是普通调用来调用 Synchronize 操作,这并不重要。重要的是这个动作现在是异步的并且不会阻塞工作线程。它将这一点委托给底层 API,该 API 目前执行冗长的 I/O 操作,使用流、套接字、数据库连接上的 BeginXXX、EndXXX 方法......重要的是要了解,如果您的 API 尚未实现这样,您不能只将同步方法包装在新线程或异步委托中并在那里执行它。我的意思是你可以,但你这样做绝对没有任何收获。

备注:不要误以为这会让你的操作更快。这没有奇迹。该操作将花费与以前完全相同的时间。只是在执行期间不会危及 ASP.NET 工作线程,并且您的其他请求将执行得更快。

于 2012-07-18T14:25:59.617 回答
0

两者用于不同的目的。从您所描述的内容来看,听起来您想使用AsyncResult异步执行方法调用。

于 2012-07-18T14:15:52.270 回答