C# 尝试从C调用长时间运行的存储过程异步时失败
我有一个长时间运行的存储过程spLongRunningProcesswhen我使用Async wait调用它时,它运行并执行得很好,但是我需要在不等待响应的情况下调用它,因为它是一个长时间运行的过程。。下面是我的代码,我遗漏了一些东西,但不能完全确定C# 尝试从C调用长时间运行的存储过程异步时失败,c#,sql,asynchronous,C#,Sql,Asynchronous,我有一个长时间运行的存储过程spLongRunningProcesswhen我使用Async wait调用它时,它运行并执行得很好,但是我需要在不等待响应的情况下调用它,因为它是一个长时间运行的过程。。下面是我的代码,我遗漏了一些东西,但不能完全确定 public async Task<ResultObject> LongSPCallAsync() { ResultObject ro = new ResultObject(); try { us
public async Task<ResultObject> LongSPCallAsync()
{
ResultObject ro = new ResultObject();
try
{
using (_context = new DbContext())
{
SqlParameter returnVal2 = new SqlParameter("@ReturnVal2", SqlDbType.Int)
{
Direction = ParameterDirection.Output
};
_context.Database.ExecuteSqlCommandAsync("EXEC @ReturnVal2 = [spLongRunningProcess]", returnVal2).ConfigureAwait(false); //<-- This NEVER runs unless I await it.?
var oooo = returnVal2.Value; //<-- just orphan code for debugging.
}
}
catch (Exception e)
{
await _logService.AddLogAsync(e, $"Error running SP:", "spLongRunningProcess");
}
return ro;
}
在Conn字符串中,我指定了异步处理=True
为了验证它是否真的在运行,我只是通过另一个进程检查数据库。正在查找我错过的内容。您应该等待调用ExecuteSqlCommandAsync:
执行wait语句时,LongSPCallAsync将返回,并且调用线程可以继续执行其他操作,直到执行了SQL命令并执行了该方法的其余部分
您可以选择不等待LongPCallasync,但需要等待ExecuteSqlCommandAsync,以便在命令完成之前不释放DbContext。此外,如果不等待ExecuteSqlCommandAsync,则无法捕获并记录从中引发的任何异常。您应该等待调用ExecuteSqlCommandAsync:
执行wait语句时,LongSPCallAsync将返回,并且调用线程可以继续执行其他操作,直到执行了SQL命令并执行了该方法的其余部分
您可以选择不等待LongPCallasync,但需要等待ExecuteSqlCommandAsync,以便在命令完成之前不释放DbContext。此外,如果您不等待ExecuteSqlCommandAsync,您将无法捕获并记录从它引发的任何异常。如果您确实:
不管存储过程是成功还是失败
不需要从存储过程返回任何数据
那么
由于退出该方法时命令仍在运行,因此不能使用。但从那以后这就不重要了
由于您没有等待它完成,因此无法查看是否发生任何异常,因此try/catch对您没有帮助
因为您不想要结果,而且无论如何也无法得到它,所以使用returnVal2变量没有意义
因此,您可以将该方法浓缩为:
公共无效LongSPCallAsync
{
新的DbContext.Database.ExecuteSqlCommandAsyncEXEC[spLongRunningProcess];
}
当然,如果您仍然需要这里已有的错误处理和日志记录,您可以在此处使用wait,而不在调用LongSPCallAsync的地方使用wait
此外,这可能是一本很好的读物:如果您确实:
不管存储过程是成功还是失败
不需要从存储过程返回任何数据
那么
由于退出该方法时命令仍在运行,因此不能使用。但从那以后这就不重要了
由于您没有等待它完成,因此无法查看是否发生任何异常,因此try/catch对您没有帮助
因为您不想要结果,而且无论如何也无法得到它,所以使用returnVal2变量没有意义
因此,您可以将该方法浓缩为:
公共无效LongSPCallAsync
{
新的DbContext.Database.ExecuteSqlCommandAsyncEXEC[spLongRunningProcess];
}
当然,如果您仍然需要这里已有的错误处理和日志记录,您可以在此处使用wait,而不在调用LongSPCallAsync的地方使用wait
另外,这可能是一本很好的读物:Wait ExecuteSqlCommandAsync。我正在使用它。。。正如我发布的。当我等待dbase调用时,它可以工作,但我不能等待它,它需要启动并忘记。为什么?当您点击wait时,该方法返回。我不能等待-然后确保您没有处理_上下文,如果没有上下文,就不能执行查询。否则你做得对。记住,火和遗忘不仅意味着我不想等待,而且我也不在乎这是否成功。你确定如果失败了,你不知道可以吗?等待ExecuteSqlCommandAsync。我正在使用它。。。正如我发布的。当我等待dbase调用时,它可以工作,但我不能等待它,它需要启动并忘记。为什么?当您点击wait时,该方法返回。我不能等待-然后确保您没有处理_上下文,如果没有上下文,就不能执行查询。否则你做得对。记住,火和遗忘不仅意味着我不想等待,而且我也不在乎这是否成功。你确定如果它失败了,你不知道它可以吗?我要把它标记为已解决,并提出警告。这基本上回答了我所寻找的问题,但真正的解决方案是前面的方法调用正在等待,而这正是阻碍UI工作的原因。然而,这在技术上是正确的。我将把它标记为已解决,并提出警告。这基本上回答了我所寻找的问题,但真正的解决方案是,前面的方法调用正在等待一段时间 这是阻碍UI工作的原因。然而,这在技术上是正确的。
await _context.Database.ExecuteSqlCommandAsync(...).ConfigureAwait(false);