ThreadPool и GUI ждут вопроса - PullRequest
1 голос
/ 17 декабря 2008

Я новичок в темах и нуждаюсь в помощи. У меня есть приложение для ввода данных, которое занимает непомерное количество времени, чтобы вставить новую запись (то есть 50-75 секунд). Поэтому я решил отправить инструкцию вставки через ThreadPool и позволить пользователю начать ввод данных для записи во время той вставки, которая возвращает новый идентификатор записи во время выполнения этой вставки. Моя проблема в том, что пользователь может нажать «Сохранить», прежде чем новый идентификатор возвращается из этой вставки.

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

while (safeToSave == false)  
{  
    Thread.Sleep(200)  
}  

Я думаю, что это плохая идея. Если я запустил метод сохранения до того, как этот протектор вернется, он застрянет.

Итак, мои вопросы:

  1. Есть ли лучший способ сделать это?
  2. Что я здесь не так делаю?

Спасибо за любую помощь.
Дуг

Изменить для получения дополнительной информации:

Он выполняет вставку в очень большую (приближаясь к максимальному размеру) базу данных FoxPro. Файл содержит около 200 полей и почти столько же индексов.
И прежде чем вы спросите, нет, я не могу изменить его структуру, как это было здесь раньше, и есть тонна унаследованного кода. Первая проблема заключается в том, что для получения нового идентификатора я должен сначала найти max (id) в таблице, затем увеличить его и проверить его. Это занимает около 45 секунд. Тогда первая вставка - это просто вставка этого нового идентификатора и поля ввода. Эта таблица не может / не может быть помещена в DBC, что исключает автоматическую генерацию идентификаторов и т. П.

@joshua.ewer
У вас правильный процесс, и я думаю, что на короткое время я просто отключу кнопку сохранения, но я буду изучать вашу идею передать его в очередь. У вас есть какие-либо ссылки на MSMQ, на которые мне следует взглянуть?

Ответы [ 5 ]

2 голосов
/ 17 декабря 2008

1) Многие :), например, вы можете отключить кнопку «сохранить», когда поток вставляет объект, или вы можете настроить Thread Worker, который обрабатывает очередь «запросов на сохранение» (но я думаю, что проблема здесь является то, что пользователь хочет изменить вновь созданную запись, поэтому отключение кнопки может быть, это лучше)

2) Я думаю, нам нужно больше кода для понимания ... (или, может быть, это проблема синхронизации, я тоже не фанат ошибок)

Кстати, я просто не понимаю, почему вставка занимает так много времени ... Я думаю, что вы должны сначала проверить этот код! <- так же, как Чарльз сказал ранее (извините, не читайте пост):) </p>

1 голос
/ 17 декабря 2008

Используйте future вместо необработанного действия ThreadPool. Выполните будущее, разрешите пользователю делать все, что он хочет, когда он нажимает Сохранить во 2-й записи, запрашивает значение из будущего. Если 1-я вставка уже завершена, вы сразу получите идентификатор, а 2-я вставка будет разрешена. Если вы все еще ожидаете 1-ю операцию, будущее заблокируется, пока она не станет доступной, а затем 2-я операция может быть выполнена.

Вы не сохраняете время, если пользователь не выполняет операцию медленнее.

1 голос
/ 17 декабря 2008

Все остальные, включая вас, решали основные проблемы (время вставки, почему вы делаете вставку, затем обновление), поэтому я буду придерживаться только технических проблем с вашим предложенным решением. Итак, если я правильно понял поток:

  • Тема 1: Начать ввод данных для запись

  • Поток 2: Фоновые вызовы в БД для получения нового идентификатора

  • Кнопка сохранения всегда включена, если пользователь пытается сохранить перед тем 2 завершается, вы кладете # 1 спать 200 мс?

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

Тем не менее, я думаю, что гораздо лучшее решение (хотя оно может быть преувеличено, если вы просто создаете интерфейс Q & D для FoxPro), - это бросить эти операции сохранения в очередь. Пользователь может набрать как можно быстрее, затем запросы помещаются в нечто вроде MSMQ, и они могут выполнять в свое время асинхронно.

0 голосов
/ 18 декабря 2008

Возможно ли подобное решение:

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

PS: Сложно это подтвердить, но помните о следующей проблеме параллелизма с тем, что вы предлагаете (с потоками или без): пользователь A начинает добавлять, пользователь B начинает добавлять, пользователь A вычисляет идентификатор 1234 как Максимальный свободный идентификатор, пользователь B вычисляет ID 1234 как максимальный свободный идентификатор. Пользователь А вставляет идентификатор 1234, Пользователь Б вставляет идентификатор 1234 = Boom!

0 голосов
/ 17 декабря 2008

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

Во-вторых, почему вы вставляете запись до того, как получите данные? Обычно приложения для ввода данных кодируются так, чтобы попытка вставки не предпринималась до тех пор, пока все необходимые данные для вставки не были получены от пользователя. Вы делаете это, потому что вы пытаетесь сначала получить новый Id из базы данных, а потом «обновить» новую пустую запись введенными пользователем данными? Если так, то почти у каждого поставщика базы данных есть механизм, в котором вы можете выполнить вставку только один раз, не зная нового идентификатора, и заставить базу данных также вернуть новый идентификатор ... Какую базу данных поставщика вы используете?

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