简体   繁体   中英

Calling a seeding method asynchronously in ASP.net MVC

I hope this question isn't too broad, but I've run into an issue in design when using the Entity Framework.

Basically my company wants our application to be able to manually upload valid databases and seed them at will, instead of having to run update database to do so. I got this aspect working easily enough by simply moving the seeding method out of the configuration file and overloading the constructor to accept a database from the uploaded path.

However, the next task that was asked of me led me to some design issues. They want me to provide an indicator on the client side that this seeding was occurring and perhaps how far in it is, through a progress bar/text output. Because the seeding method is running synchronously this has proved troublesome because the client side will be locked up for the duration of it being run.

As the seeding method takes about 20 minutes to complete this isn't ideal as the client would be left unsure of how long they will have to wait before they can do something again. I tried to implement it using an async controller but it complained that the seeding method is of type void. The actionresult that's being called on the file upload looks something like this

    [HttpPost]
    public ActionResult Index(HttpPostedFileBase file)
    {

        if (file.ContentLength > 0)
        {
            var fileName = Path.GetFileName(file.FileName);
            string date = DateTime.Now.ToString("MM-dd-yyyy-HHmm-");
            fileName = date + fileName;
            var path = Path.Combine(Server.MapPath("~/bin/SampleData"), fileName);
            file.SaveAs(path);
            //create config instance and seed path
            Reseed reseed = new Reseed(fileName);
            reseed.Seed(db);
            GetTimeStamp(DateTime.Now);
        }

        return RedirectToAction("Index");
    }

Does anyone know if there would be a good way to design this in a way that it could be run asynchronously?

Seeding asynchronously on the server will only serve to free up a thread for the duration of the process (if it is IO bound), in order to return you will end up waiting for this to finish up anyway (if you were to make the controller async). Its not a good candidate for parallelising as its not a compute bound operation either.

Either way, you want to get progress back up to the client so there are a few approaches and technologies worth considering:

Web sockets, using SignalR, whereby you can have a connection from the server to the client and push content on the connection to the client. This downgrades to long polling where the software doesnt support it. Might be a bit overkill as its bidirectional.

Server Sent Events, which has less overhead than Web sockets and is half-duplex from server to client, it allows pushing of content from server to client also

A slightly different approach would be returning/redirecting from the screen and sending an email to the user indicating when the process has finished. You could kick off a scheduled task, or send a command to something out of process to start a batch process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM