首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在后台Web中运行存储过程

在后台Web中运行存储过程
EN

Stack Overflow用户
提问于 2015-08-05 10:21:19
回答 1查看 2.1K关注 0票数 1

在我的Web应用程序中,我需要这样做:应用程序中的Best way to run a background task in ASP.Net web app and also get feedback?用户可以上传一个excel文件,然后将其数据导入数据库中的表中。这一切都很好,但是导入过程可能需要很长的时间(如果excel有很多行,则大约需要20分钟),当进程启动时,页面会被阻塞,用户不得不一直等待。我需要在后台运行这个导入进程。

我有一个带有POST方法的控制器:

代码语言:javascript
复制
[HttpPost]
public async Task<IHttpActionResult> ImportFile(int procId, int fileId)
{
    string importErrorMessage = String.Empty;

    // Get excel file and read it
    string path = FilePath(fileId);
    DataTable table = GetTable(path);

    // Add record for start process in table Logs
    using (var transaction = db.Database.BeginTransaction()))
    {
        try
        {
            db.uspAddLog(fileId, "Process Started", "The process is started");
            transaction.Commit();
        }
        catch (Exception e)
        {
            transaction.Rollback();
            importErrorMessage = e.Message;
            return BadRequest(importErrorMessage);
        }
    }

    //Using myHelper start a store procedure, which import data from excel file
    //The procedure also add record in table Logs when it is finished
    using (myHelper helper = new myHelper())
    helper.StartImport(procId, fileId, table, ref importErrorMessage);

        if (!String.IsNullOrEmpty(importErrorMessage))
        return BadRequest(importErrorMessage);

    return Ok(true);
}

我还有一个GET方法,它返回有关文件及其过程的信息。

代码语言:javascript
复制
[HttpGet]
[ResponseType(typeof(FileDTO))]
public IQueryable<FileDTO> GetFiles(int procId)
{
    return db.LeadProcessControl.Where(a => a.ProcessID == procId)
                                .Project().To<FileDTO>();
}

它像这样返回JSON:

代码语言:javascript
复制
{
  FileName = name.xlsx
  FileID = 23
  ProcessID = 11
  Status = Started
}

此方法适用于网格。

代码语言:javascript
复制
File name | Status | Button to run import | Button to delete file

这个Status来自Logs表,并在FileDTO中放置了最后一个值,例如,如果我上传文件,那么当我运行Importstatus时,status将是“上传的文件”,当它完成时,status将是“完整的”。但是现在当导入进程运行时页面被锁定了,所以状态总是“完整”的。

因此,我需要在后台运行过程,如果已经更改,GET方法应该返回新的Status。有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-06 03:09:27

向方法添加异步不使您的方法调用异步。它只是表示在等待某个网络/磁盘IO时,处理当前请求的线程可以被重用来处理其他请求。当客户端调用此方法时,它只会在方法完成后获得响应。换句话说,异步完全是服务器端的事情,与客户端调用无关。您需要在一个单独的线程中启动长时间运行的进程,如下所示。但是,最佳做法是不要将web应用程序用于如此长时间运行的处理,而是在单独的windows服务中进行长时间处理。

代码语言:javascript
复制
[HttpPost]
    public async Task<IHttpActionResult> ImportFile(int procId, int fileId)
{
string importErrorMessage = String.Empty;

// Get excel file and read it
string path = FilePath(fileId);
DataTable table = GetTable(path);

// Add record for start process in table Logs
using (var transaction = db.Database.BeginTransaction()))
{
    try
    {
        db.uspAddLog(fileId, "Process Started", "The process is started");
        transaction.Commit();
    }
    catch (Exception e)
    {
        transaction.Rollback();
        importErrorMessage = e.Message;
        return BadRequest(importErrorMessage);
    }
}

         //Start long running process in new thread
         Task.Factory.StartNew(()=>{

         using (myHelper helper = new myHelper())
        {
           helper.StartImport(procId, fileId, table, ref importErrorMessage);

          //** As this code is running background thread you cannot return anything here. You just need to store status in database. 

         //if (!String.IsNullOrEmpty(importErrorMessage))
         //return BadRequest(importErrorMessage);
       }

        });

//You always return ok to indicate background process started
return Ok(true);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31829706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档