Потоки с использованием BackgroundWorker - PullRequest
0 голосов
/ 15 июля 2009

У меня есть сценарий. У меня есть список идентификаторов пользователя, отображаемых в форме Windows. Как только я нажимаю один из идентификаторов пользователя, я иду и получаю информацию о пользователе из БД. Чтобы сохранить отзывчивость приложения, при выборе измененного события из списка я создаю новые объекты BackgroundWorker (BW) и попадаю в БД. Я показываю 'Поиск пользователя' abc '...' в строке состояния.

Теперь, если пользователь перемещается между идентификаторами пользователя с помощью клавиш со стрелками (4-5 раз), в соответствии с приведенным выше дизайном я создал несколько объектов BW для выполнения запроса. Но, наконец, когда данные возвращаются для конкретного пользователя (который может не совпадать с тем, где пользователь в данный момент выбран в просмотре списка), поскольку это был асинхронный вызов, я все равно в итоге отображаю всех пользователей в строке состояния.

То, что я хотел бы сделать, я хочу пойти и получить детали только для последнего пользователя. До этого времени я хочу отображать только «Поиск пользователя ...».

Пожалуйста, дайте мне знать решение для этого ...

Ответы [ 4 ]

2 голосов
/ 15 июля 2009

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

1 голос
/ 16 июля 2009

Как насчет того, чтобы подождать секунду или две перед тем, как запустить фоновый рабочий?

После того, как пользователь щелкнет по идентификатору пользователя, запустите таймер с интервалом в 1 секунду, а через одну секунду запустите ваш BackgroundWorker. Если пользователь нажимает на другой идентификатор пользователя, сбросьте таймер. Таким образом, если пользователь продолжает нажимать на разные идентификаторы в быстрой последовательности, вы ничего не будете делать. После того, как пользователь сделал перерыв, вы запускаете фонового работника.

0 голосов
/ 15 июля 2009

Я использовал это для отмены BackgroundWorkers и раньше, и это прекрасно работало.

    public void cancelWorker( BackgroundWorker worker )
    {
        if (worker != null)
        {
            if (worker.IsBusy)
            {
                worker.CancelAsync();

                while (worker.IsBusy)
                {
                    Application.DoEvents();
                }
            }
        }
    }

Я слышал спор об использовании Application.DoEvents (); но у меня были проблемы с бесконечными циклами, если я использовал Thread.sleep или другой.

Возможно, вы захотите использовать какой-либо опрос, чтобы вы не столкнулись с backgroundWorkers, перебирающими друг друга - особенно если обратный вызов заканчивается вызовом чего-то вроде пользовательского интерфейса в отдельном потоке, чтобы они могли фактически вызвать условия гонки.

0 голосов
/ 15 июля 2009

Один из вариантов - сохранить строковое поле в форме, содержащей идентификатор пользователя. В фоновом режиме, после того как вы нажмете на БД, убедитесь, что это поле по-прежнему равно идентификатору пользователя, которому оно было передано, EDIT : и, если оно отличается, создайте результат null. Управляйте полем, используя методы класса Interlocked, чтобы избежать необходимости блокировки. Это неправильно; ссылочные типы могут быть прочитаны и записаны атомарно с помощью Interlocked.

2 nd РЕДАКТИРОВАТЬ : Вы также можете вернуть исходный идентификатор пользователя из фонового рабочего вместе с результатом и проверить, что это самый последний щелчок в обработчике Completed.

В качестве альтернативы, если вы сохраняете ссылки на все BackgroundWorkers, вы можете использовать их поддержку отмены.

...