C #: возможно ли отменить запрос linq2sql? - PullRequest
5 голосов
/ 04 марта 2009

Можно ли отменить запрос linq2sql? Например, если я создал запрос, выполнение которого занимает некоторое время, я бы хотел, чтобы пользователь мог отменить его. У кого-нибудь есть хорошие идеи по этому поводу?

Ответы [ 4 ]

2 голосов
/ 04 марта 2009

Если вы установите свойство CommandTimeout (секунд) DataContext , оно автоматически сгенерирует исключение по истечении времени ожидания.

2 голосов
/ 05 марта 2009

Итак, согласно комментарию Ричарда Сзалая :

Лучше всего выполнить запрос в фоновом потоке и просто отписаться от событий объекта-контейнера, когда пользователь нажмет кнопку Отмена.

И я думаю, что согласен с тем, что сейчас это хороший обходной путь. Я хотел бы видеть некоторые функции асинхронных запросов, уже находящиеся в фреймворке, но пока это не произойдет, это должно будет сделать.

Еще не начали реализовывать это (сначала нужно закончить некоторые другие вещи), но одним способом это могло бы работать:

  • В рабочем потоке выполняйте запросы в отдельном потоке запросов, а затем присоединяйтесь к этому потоку, пока он не закончится.
  • Когда пользователь нажимает кнопку отмены, вызовите метод Interrupt рабочего потока, который затем получит ThreadInterruptedException и прекратит ждать завершения потока запроса.

Может добавить код позже, когда я его сделаю. Но посмотрим как получится красиво: p

0 голосов
/ 28 ноября 2012

Я знаю, что этот ответ довольно поздно, но вот как я это делаю:

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" );
    }
}
0 голосов
/ 04 марта 2009

Я бы сказал, что вам, вероятно, нужно запустить его в отдельном потоке и вместо этого отменить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...