C#:是否可以取消linq2sql查询?

时间:2009-03-04 08:26:09

标签: c# linq-to-sql

是否可以取消linq2sql查询?就像我构建了一个需要一段时间才能运行的查询一样,我希望用户能够取消它。有没有人对此有任何好的想法?

4 个答案:

答案 0 :(得分:2)

如果设置CommandTimeoutDataContext(秒)属性,它将在超时后自动抛出异常。

答案 1 :(得分:2)

所以,根据Richard Szalay的评论:

  

最好的办法是在后台线程中运行查询,只需在用户点击取消时取消订阅容器对象的事件。

我认为我同意这是一个好的解决办法。我希望看到的是框架中已有的一些异步查询功能,但在此之前必须这样做。

还没有开始实现这个(必须先完成其他一些事情),但有一种方法可行:

  • 在工作线程中,在单独的查询线程中执行查询,然后加入该线程直到完成。
  • 当用户点击取消时,调用工作线程的Interrupt方法,然后获取ThreadInterruptedException并停止等待查询线程完成。

我可以在以后添加一些代码。但我们会看到它的结果有多漂亮:p

答案 2 :(得分:0)

我知道这个答案有点晚,但我就是这样做的:

class Program
{        
    public class Person
    {
        public string Name;
        public int Age;
    }        

    public static void ExecuteQueryAsync ( IEnumerable<Person> collectionToQuery , Action<List<Person>> onQueryTerminated , out Action stopExecutionOfQuery )
    {
        var abort = false;

        stopExecutionOfQuery = () =>
        {
            abort = true;
        };            

        Task.Factory.StartNew( () =>
        {
            try
            {
                var query = collectionToQuery.Where( x =>
                {
                    if ( abort )
                        throw new NotImplementedException( "Query aborted" );

                    // query logic:
                    if ( x.Age < 25 )
                        return true;
                    return
                        false;
                } );

                onQueryTerminated( query.ToList() );

            }
            catch
            {
                onQueryTerminated( null );
            }
        });
    }


    static void Main ( string[] args )
    {
        Random random = new Random();

        Person[] people = new Person[ 1000000 ];

        // populate array
        for ( var i = 0 ; i < people.Length ; i++ )
            people[ i ] = new Person() { Age = random.Next( 0 , 100 ) };

        Action abortQuery;
        ExecuteQueryAsync( people , OnQueryDone , out abortQuery );

        // if after some time user wants to stop query:
        abortQuery();

        Console.Read();
    }

    static void OnQueryDone ( List<Person> results )
    {
        if ( results == null )
            Console.WriteLine( "Query was canceled by the user" );
        else
            Console.WriteLine( "Query yield " + results.Count + " results" );
    }
}

答案 3 :(得分:-1)

我会说你可能需要在一个单独的线程上运行它并取而代之。