C#停止ExecuteQuery

时间:2014-03-28 06:18:38

标签: c# datacontext

我有DataContext我正在运行.ExecuteQuery以返回一些结果。

我想在一段时间后或者当用户停止查询时完全停止查询,但我不知道该怎么做。

我试图对此进行一些研究,没有结果。

using(SomeDataContext db = new SomeDataContext)
{
    db.CommandTimeout = 10; // Test purposes

    List<Something> sme = new List<Something>;

    // I want to be able to cancel this
    sme = db.ExecuteQuery<Something>("Stored Procedure that may take some time").ToList();
}

3 个答案:

答案 0 :(得分:2)

最简单的方法是废弃LinqToSQL中的所有内容(这是一种破碎且不受支持的技术),用于EnityFramework。然后你可以使用DbContext.Database.ExecuteSqlCommandAsync(String, CancellationToken, Object[])你可以使用取消令牌来解除查询。注意。 LinqToSQL不支持取消。

但是,您也可以直接使用ADO.Net DbCommand执行此操作。它非常简单。

public Task RunCommand(CancelationToken cancel)
{

    using(var connection = new DbConnection())
    {
        connection.Open();
        using(var command = connection.CreateCommand())
        {
            //setup the command
            await command.ExecuteNonQueryAsync(cancel.Token);
        }

    }
}

public void Main()
{
    var cancel = new CancellationTokenSource();
    RunCommand(cancel.Token);
    cancel.Cancel();
}

答案 1 :(得分:1)

这是两个不同的问题:

  • 要在设定的时间后停止执行查询,可以使用连接超时。根据您的数据库,您可以在数据库上查询最长运行时间。

  • 让用户停止执行会有点困难。您必须执行Query async以将controll返回给用户,但维护对Connection的引用,然后允许用户关闭Connection。根据您的数据库,数据库应该注册没有人在等待回复,然后停止执行。

答案 2 :(得分:0)

我认为您可以通过应用逻辑来实现此功能。

逻辑:

当您启动 ExecuteQuery 时,在此之前使用交易并在成功完成执行提交交易之后。

同时如果您想停止执行程序回滚 交易关闭连接

风险:你必须确保并测试它能否维护交易和连接,否则你的数据库可以进入* DeadLock *

参考下面的示例代码和http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

System.Data.Common.DbTransaction trans = null;

在课堂范围内宣布。

//dbAdmin is my DataContext

dbAdmin.Connection.Open();
trans = dbAdmin.Connection.BeginTransaction();
dbAdmin.Transaction = trans;

 try
  {
   //Perform ExecuteQuery
    trans.Commit();
  }
 catch(Exception)
  {
   // Rollback transaction
   if (trans != null)
   trans.Rollback();
   return "Some error occured while saving record. Transaction has being rollbacked.";
  }

并在Stop Execute事件中

 if (trans != null)
   trans.Rollback();