如何立即停止正在运行的DbContext.SaveChanges()

时间:2019-05-28 08:02:25

标签: c# entity-framework entity-framework-6

我目前正在开发服务。服务关闭的时间有限(4s)。

我有一个关闭程序,这还会通过EF6将一些次要数据推送到sql数据库。

...

关机!

第一步(停止正常运行)

step2将一些关闭数据推送到数据库

step3最终关闭,处置所有问题。

该应用具有多个上下文,并且以重试一分钟的方式设置了一种执行策略。我想这样保留。

现在很可能发生数据库关闭的情况,因此由于执行策略的原因,对数据库的此调用将花费很长时间,最多1分钟。

这是超过4s的方式,因此我想选择立即停止操作。我不能要求更多时间。

到目前为止,我已经尝试了SaveChangesAsync(cancellationToken);但这仍然会继续执行一分钟,取消令牌不会执行任何操作。然后,我尝试使用第二个Task来调用上下文上的dispose,关闭连接等。这有时似乎起作用,但是在其他情况下,它仍然要等待一分钟,然后抛出异常。

var timeoutTask = Task.Run(() =>
            {
                while (true)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        context.Database.Connection.Close();
                        Debug.WriteLine($"{DateTime.Now:G} {nameof(cancellationToken)} token is canceled!");
                        using(context) { }
                        return;
                    }

                    Task.Delay(10, timeoutTaskTokenSource.Token).Wait(timeoutTaskTokenSource.Token);

                    timeoutTaskTokenSource.Token.ThrowIfCancellationRequested();
                }
            }, cancellationToken);

现在我正在考虑创建一个线程并中止它,但是我希望我能找到一个更明智的解决方案。

编辑:

在连接字符串中设置了连接超时:

数据源=本地主机;初始目录= MyDb;集成安全性= False;用户ID = someuser;密码= somepassword; MultipleActiveResultSets = True;连接超时= 1;应用程序ame = somename; ConnectRetryCount = 0; ConnectRetryInterval = 1

命令超时也设置为1。

1 个答案:

答案 0 :(得分:0)

如果数据库不可用,则可以使用连接字符串的Connection Timeout属性。延迟后,这将终止连接尝试。

如果您想中止命令,则可以使用CommandTimeout属性。

context.Database.CommandTimeout = 5;