Это первый случай, когда я пытался использовать потоки в приложении. Я знаю, что этот вопрос задавали раньше, но из решений, которые я рассматривал, я не вижу, как их применять в моей ситуации.C# Как проверить, что поток закончен, прежде чем запускать другой
У меня есть программа, где datagridview обновляется на таймере каждые 60 секунд. Данные поступают из базы данных SQL. Этот таймер также запускает рабочий поток для поиска конкретного устройства Bluetooth и обновления базы данных на основе его результатов в фоновом режиме. Поиск Bluetooth особенно медленный, поэтому я помещаю его в рабочий поток.
Моя проблема в том, что новый рабочий поток начинается до того, как предыдущий закончен. По крайней мере, это единственное логическое объяснение ошибок, которые я получаю. Большая отдача - это ошибка блокировки файла, когда единственной вещью, которая может блокировать файл, является другой рабочий поток из того же приложения.
Вот код, который я использую, чтобы начать фоновый поток.
private void timerScreenRefresh_Tick(object sender, EventArgs e)
{
if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "");
// If the user is not on a Remote desktop connection
if (!remoteDesktopUser)
{
// Run the Bluetooth Search in a worker thread
Thread thread = new Thread(new ThreadStart(this.checkProximity));
thread.IsBackground = true;
thread.Start();
}
// Load User Data from the DB and display on the screen
loadUserData();
}
Казалось бы, что решение использовать thread.IsAlive(), но я не смог найти хороший пример. Кажется странным попытаться проверить существование потока, когда я только что создал новый, с «Thread thread = new Thread()»
Очевидно, что я что-то упустил. Я использую Visual Studio 2008. Спасибо за любые идеи Давид
UPDATE
на основе предлагаемого решения по krw12572 ниже я попытался это ...
Я изменил! = К ==, потому что я все еще хочу каждый раз запускать метод loadUserData() в основном потоке.
В редакторе я получаю зеленое подчеркивание на «_bluetoothSearchThread», сообщая мне, что поле никогда не назначается и всегда будет иметь значение NULL.
Во время выполнения я получаю сообщение об ошибке «Ссылка на объект, не установленное на экземпляр объекта» в этой строке.
Как это значение присваивается?
private Thread _bluetoothSearchThread;
private void timerScreenRefresh_Tick(object sender, EventArgs e)
{
if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "");
// Check if Worker Thread is already running.
if (_bluetoothSearchThread == null && _bluetoothSearchThread.IsAlive)
{
if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "Previous Worker Thread not running");
// If the user is not on a Remote desktop connection
if (!remoteDesktopUser)
{
// Check if the users mobile phone is within range
// Run the Bluetooth Search in a worker thread
Thread thread = new Thread(new ThreadStart(this.checkProximity));
thread.IsBackground = true;
thread.Start();
}
}
else
{
if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "Worker Thread still running don't start another one");
}
// Load User Data from the DB and display on the screen
loadUserData();
}
Update 2
OK Я думаю, что я понял это. Я изменил! = Нулевое обратно к тому, как оно было, и повернул IF и Else Around в другую сторону.
Тогда я должен был использовать мой мозг немного и изменил «нить», чтобы «_bluetoothSearchThread»
Теперь код компилируется и работает. Теперь мне просто нужно проверить его, вызвав условия, которые вызывают ошибку блокировки файлов, чтобы увидеть, действительно ли я исправил исходную проблему. Если это сработает, я отвечу krw12572 как правильно.
Обновление 2.5 я также должен был переместить эту линию так, что не создает новый экземпляр слишком рано
_bluetoothSearchThread = new Thread(new ThreadStart(this.checkProximity));
Так что это рабочий раствор.
private Thread _bluetoothSearchThread;
private void timerScreenRefresh_Tick(object sender, EventArgs e)
{
if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "");
// Check if Worker Thread is already running.
if (_bluetoothSearchThread != null && _bluetoothSearchThread.IsAlive)
{
// Thread is still running. Just log it and move on.
if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "******** Worker Thread still running don't start another one *********");
}
else
{
if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "Previous Worker Thread not running");
// If the user is not on a Remote desktop connection
if (!remoteDesktopUser)
{
// Check if the users mobile phone is within range
// Run the Bluetooth Search in a worker thread
_bluetoothSearchThread = new Thread(new ThreadStart(this.checkProximity));
_bluetoothSearchThread.IsBackground = true;
_bluetoothSearchThread.Start();
}
}
// Load User Data from the DB and display on the screen
loadUserData();
}
Здесь ваш результат: http://stackoverflow.com/questions/12949024/detecting-a-thread-is-already-running-in-c-sharp-net –
@BALA Я видел это решение раньше. Это казалось слишком сложным, и я этого не понимал. Я постараюсь и слепо следовать за ним завтра и посмотреть, выходит ли что-то работоспособное. –
Возможный дубликат [Как проверить завершение выполнения Thread] (http://stackoverflow.com/questions/2773479/how-to-check-if-thread-finished-execution) –