3

I have an issue with using a Database in a thread in my asp.net Application. When I want to start my application I want to start a thread called "BackgroundWorker" with it, which runs in the background till the whole application is stopped.

The problem is that I have massive problems with the dbContext in the thread.

I I try to start the walker in my Startup.cs in the methods "ConfigureServices" or "Configure" and then initialize the dbContext in the constructor in the Walker like this "dbContext = new ApplicationContext()" it tells me that the connection is not configured, when I try to operate in the while(true) queue on the database. If I write an own Controller for the Walker which receives a ApplicationContext in his constructor and then starts a Thread like this, if i call this controller once with a GET Request:

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
                {
                 ...
                }
            }

        }

Then I receive an System.ObjectDisposedException that the object is already disposed inside the while (true) queue.

I tried those and similar things in many different ways but allways receive exceptions like these two or that the database connection is closed.

Can somebody help me and tell me, how this works?

Thank you!

4
  • Which method is your "while (true)" code in? Commented Jan 15, 2016 at 21:25
  • 4
    Why are you doing this? Might be an easier way to solve whatever problem you're having that is making you want to try to have a thread like this in a web app. Generally speaking (and I do mean generally, it's subjective), this would be a bad idea. Commented Jan 15, 2016 at 21:25
  • Please explain the architecture for this project, is your API supporting a Web Application? Commented Jan 15, 2016 at 21:27
  • @GabrielLuci edited my question. The whilte(true) code is in the DoBackGroundWork() method. Nikki9696: I want a thread, that searches every 30 seconds in the database, if a date is expired and then sends an email with a link, referring to the the that expired in the database BrianOgden: Im a beginner in programming, so I'm not sure, what you wanna hear, but i try it: Weh have an asp.net 4.5 mvc application. The communication to the front end is over Restful Web Api Controller in the backend and AngularJS Controller in the Frontend. We are using EntityFramework 7 code first for the database. Commented Jan 15, 2016 at 21:31

2 Answers 2

3

Generally, server side multithreading for Web Applications does not happen often and is, most times, a huge no no.

Conceptually, your server is "multithreaded", it handles many HTTP requests from clients/users/other servers. For mobile and web architecture/design, your server(s) process multiple requests and your clients are handling asynchronous calls and dealing with waiting for responses from long running calls like your API method StartWorker.

Think of this scenario, you make a request to your WebAPI method StartWorker, the client, making the request is waiting for a response, putting the work on another thread does nothing as the client is still waiting for a response.

For example, let's consider your client an HTML web page with an Ajax call. You call StartWorker via Ajax, you will be loading data into a HTML table. You will desire, from a UX perspective, to put up a progress spinner while that long running StartWorker responds to your HTML Page Ajax call request. When StartWorker responds, the Ajax call loads the HTML table with the StartWorker response. StartWorker has to respond with the data. If StartWorker responds beforehand than you will have to send a push notification, via SignalR, for example, when the other thread completes and has the data you need for the HTML table.

Hopefully, you see, the call to the WebAPI method, takes the same amount of time from a Ajax request/response perspective, so multithreading becomes pointless in this scenario, a most common web application scenario.

You can have your client UI load other UI elements, showing a progress spinner in HTML table UI area, until your database call is complete and responds with the data to your Ajax call. This way your users know things are happening and something is still loading.

If you still need your additional thread in your API for your project needs, I believe you have to be using Entity Framework 6 or greater to support asynchronous queries, see this tutorial:

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

UPDATE

Now that I know you need to run a SQL query on a repeating frequency of time, and you have an Azure Web App, what you want to use is Azure Automation if you are using Sql Azure or create a Sql Server Job if you are using a Sql Server instance as your backend

Sign up to request clarification or add additional context in comments.

10 Comments

Thanks for this answer! But if not using a thread, how would you try to solve my problem: I want some process that permanently runs on the server and searches through the database, whether a date has expired
That would be a Windows Service you are looking for, or a Sql Server Job, probably a Sql Server Job, that runs, say every 30 seconds and queries records, you would then fire off a notification from the Sql Server Job, for example a HTTP request to your API, from your API you would have to send a push notification, via SignalR, for example, for your client UIs to update. Or again, a Windows Service is what you need, same scenario, the Windows Service queries the database, when needed you call your API, and the send a notification to clients.
I don't know whether you did not understand completely, what I am trying to do or maybe I did not understand, what you mean: I don't want to send anything to a client. Even if there would be no client connected, I just want something that looks through one table in my database, looks whether a date expired and then simple send a mail via MailMessage. I just tried to inform myself a little about Windows Services and this seems to look kind of overpowered and complicated for my Purpose, with a simple web application hosted as an azure web app
Yup a Sql Server Job would be perfect, I use them all the time for such a scenario, you have the job run the query and send the email, Sql Server Jobs have this all built in very easily, the problem if you are using Sql Azure you can set this up via Azure automation: azure.microsoft.com/en-us/blog/…
You definitely want a Sql Server Job for this, or use Azure Automation if you are using Sql Azure
|
1

DbContext is not thread safe. You need to create a new context from inside your thread.

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

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

3 Comments

I tried this, but then I receive an 'System.NullReferenceException' at ' if (dbContext.PollModels.Any())'
Are you sure you had 'if (dbContext.PollModels.Any())' and not 'if (_dbContext.PollModels.Any())' - note the underscore. You have the underscore in your question, which is a different variable than what is passed to your DoBackGroundWork method.
Oh, i really had a small switch of letters, but I corrected this and now I receive this exception, trying Ians solution: "An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.Core.dll Additional information: No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.