ASP.NET Web Api,线程中的数据库连接

时间:2016-01-15 21:17:19

标签: c# asp.net asp.net-mvc multithreading

我在asp.net应用程序的线程中使用数据库时遇到问题。 当我想启动我的应用程序时,我想启动一个名为" BackgroundWorker"用它,它在后台运行,直到整个应用程序停止。

问题是我在线程中遇到了dbContext的大量问题。

我尝试在方法" ConfigureServices"中的Startup.cs中启动walker。或"配置"然后在Walker的构造函数中初始化dbContext,就像这样" dbContext = new ApplicationContext()"它告诉我,当我尝试在数据库上的while(true)队列中操作时,没有配置连接。 如果我为Walker编写一个自己的Controller,它在构造函数中接收一个ApplicationContext然后启动这样的Thread,如果我用GET请求调用一次这个控制器:

public BackgroundWorker(ChronicusContext dbContext)
    {
        _dbContext = dbContext;
        _messageService = new MailMessageService();
    }

    // GET: api/backgroundworker
    [HttpGet]
    [Route("start")]
    public void StartWorker()
    {

        //Thread thread = new Thread(this.DoBackGroundWork);
        Thread thread = new Thread(() => DoBackGroundWork(this._dbContext));
        thread.Start();

    }

  public void DoBackGroundWork(ChronicusContext _dbContext)
    {
        while (true)
            {
                if (_dbContext.PollModels.Any())  //Here is the exception
                {
                 ...
                }
            }

        }

然后我收到一个System.ObjectDisposedException,该对象已经放在while(true)队列中。

我以许多不同的方式尝试了这些和类似的东西,但总是收到像这两个例外或数据库连接关闭的异常。

有人可以帮我告诉我,这是怎么回事?

谢谢!

2 个答案:

答案 0 :(得分:3)

通常,Web应用程序的服务器端多线程不会经常发生,并且大多数情况下都是不可能的。

从概念上讲,您的服务器是"多线程",它处理来自客户端/用户/其他服务器的许多HTTP请求。对于移动和Web架构/设计,您的服务器处理多个请求,您的客户端正在处理异步调用,并处理等待API方法StartWorker等长时间运行调用的响应。

想想这个场景,你向WebAPI方法StartWorker,客户端发出请求,让请求等待响应,将工作放在另一个线程上什么都不做,因为客户端仍在等待响应。

例如,让我们将您的客户端视为带有Ajax调用的HTML网页。您通过StartWorker致电Ajax,您将把数据加载到HTML表格中。从UX的角度来看,您希望在长时间运行StartWorker响应HTML页面Ajax调用请求时设置进度微调器。当StartWorker响应时,Ajax调用会加载带有StartWorker响应的HTML表。 StartWorker必须回复数据。如果StartWorker事先响应,则必须通过SignalR发送推送通知,例如,当另一个线程完成并拥有HTML表所需的数据时。

希望您看到,对WebAPI方法的调用从Ajax请求/响应角度来看需要相同的时间,因此多线程在这种情况下变得毫无意义,这是一种最常见的Web应用程序方案。

您可以让客户端UI加载其他UI元素,在HTML表UI区域中显示进度微调器,直到数据库调用完成并响应Ajax调用的数据。通过这种方式,您的用户知道事情正在发生,而且仍在加载某些内容。

如果您的API中仍需要额外的线程以满足您的项目需求,我相信您必须使用Entity Framework 6或更高版本来支持异步查询,请参阅本教程:

http://www.codeproject.com/Tips/805923/Asynchronous-programming-in-Web-API-ASP-NET-MVC

<强>更新

现在我知道您需要在重复的时间内运行SQL查询,并且您有一个Azure Web App,如果您使用的是Sql Azure或创建一个Azure Automation,那么您要使用的是Sql Server Job {3}}如果您使用Sql Server实例作为后端

答案 1 :(得分:1)

DbContext不是线程安全的。您需要从线程内部创建一个新的上下文。

public void DoBackGroundWork()
{
    ChronicusContext anotherContext= new ChronicusContext();

    while (true)
    {
       if (anotherContext.PollModels.Any())
       {
          ...
       }
    }
}