Прерывание потока в ASP.NET - PullRequest
0 голосов
/ 27 июля 2010
protected System.Threading.Thread m_searchthread = null;

Вопрос: Я реализовал алгоритм поиска, который пользователь может запустить с веб-сайта ASP.NET.

Когда пользователь нажимает кнопку «Пуск», выполняется этот код:

m_searchthread = new System.Threading.Thread(new System.Threading.ThreadStart(Search));
m_searchthread.IsBackground = true;
m_searchthread.Start();

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

m_searchthread.Abort();

Моя проблема сейчас: обратная передача кнопки прерывания сбрасывает m_searchthread в NULL ...

Мне известно о том, что поток должен быть прерван с помощью флага. Основная проблема заключается в следующем: как остановить поток, когда вы потеряете все переменные?

Ответы [ 5 ]

2 голосов
/ 27 июля 2010

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

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

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

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

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

1 голос
/ 27 июля 2010

Непосредственная проблема заключается в том, что вы пытаетесь использовать переменную-член (поле) для хранения потока.

Если вы сохраните его как Session["MyThreadKey"] = myThread;, вы по крайней мере сможете вернуть свою ветку в следующий постбэк. Нравится myThread = Session["MyThreadKey"];

И тогда вы можете начать думать о том, как избежать Thread.Abort.

Возможно, вы захотите обернуть поток в объект, который также содержит флаг остановки. (а затем сохранить этот объект в сеансе).


Как уже отмечалось, это будет работать только на одном сервере. Лучше всего было бы определить службу (WCF) для поиска.

0 голосов
/ 12 марта 2011

Чтобы остановить поток на основе флага, вы должны реализовать его следующим образом:

  1. Определить сам флаг в статическом классе или модуле, где он доступенв цепочку:

    bool StopTheThread = false;
    
  2. Внутри вашей цепочки проверьте этот флаг где-нибудь внутри вашей петли, чтобы изящно выйти из цепочки!

    void SearchProc()
    {
        bool exitCond = False;
        while (!exitCond)
        {
            //some execution
            //some execution
            //some execution
            //check for the thread-abort flag:
            if (StopTheThread)
            {
                System.Threading.Thread.Suspend(); //this will suspend the current thread
            }
        }
    }
    
0 голосов
/ 27 июля 2010

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

Я предлагаю вам использовать Quartz.NET.Есть полезный ответ об использовании его в Asp.NET: Как использовать Quartz.net с ASP.NET

0 голосов
/ 27 июля 2010

Почему бы не сохранить флаг в Session или ViewState и выполнить проверку в событии загрузки страницы.

...