Запустите один и тот же поток дважды - второй раз после завершения первого

1

Поэтому я создал Thread, который выполняет одну функцию, которая зависит от глобальной переменной. После этого я хотел бы изменить эту переменную и запустить поток еще раз, чтобы он снова выполнил мою процедуру с помощью другого аргумента. Проблема в том, что я не могу понять, когда мой Thread закончил. После многих поисковых запросов я не нашел ничего, что могло бы мне помочь. Может ли кто-то здесь помочь? Заранее спасибо. Некоторый код был бы оценен. Вот мой:

//temp_folder is global variable

temp_folder = APPDATA + "Local" + "\\" + "Temp\\";

Thread oThread = new Thread(new ThreadStart(clean_temp));
oThread.Start();

//Here I should wait for this oThread to finish, then change the temp_folder
//variable mentioned in comment down and start once again

//temp_folder = WINDIR + "\\" + "Temp\\";
//oThread.Start();

Вот процедура clean_temp(). И да, это графическое приложение.

public void clean_temp()
{
DirectoryInfo directory = new DirectoryInfo(temp_folder);

try
{
    DirectoryInfo[] folders = directory.GetDirectories();

    foreach (DirectoryInfo folder in folders)
    {
        temp_folder = temp_folder + folder.Name + "\\";
        clean_temp();
        temp_folder = temp_folder.Replace(folder.Name + "\\", "");
    }
}
catch { }

long sz;
double size, trenutna;

foreach (FileInfo file in directory.GetFiles())
{
    sz = file.Length;
    size = (double)sz / 1024.0;
    trenutna = Convert.ToDouble(lbl_junk_size.Text);
    trenutna += size;

    MethodInvoker mi_invoker_size_change = new MethodInvoker(()=> lbl_junk_size.Text = trenutna.ToString());
    lbl_junk_size.Invoke(mi_invoker_size_change);

    MethodInvoker mi_invoker_count_change = new MethodInvoker(() => lbl_junk.Text = (Convert.ToInt64(lbl_junk.Text) + 1).ToString());
    lbl_junk.Invoke(mi_invoker_count_change);
}
}
  • 0
    Вместо этого лучше использовать класс ThreadPool , IMO.
  • 1
    Является ли основной поток частью приложения Windows GUI? Или вы планируете делать что-то еще, пока происходит очистка?
Показать ещё 2 комментария
Теги:
multithreading
thread-safety

3 ответа

4

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

Например:

Thread oThread = new Thread(new ThreadStart(clean_temp));
oThread.Start();

oThread.Join();
  • 0
    Пробовал это, но по какой-то причине моя программа зависает, когда я делаю это: /
  • 2
    Он будет зависать, потому что Join () заставляет основной поток ждать, пока поток не завершится.
Показать ещё 1 комментарий
2

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

В большинстве случаев вы будете делать это, используя API-интерфейс Task в.NET. Задачи дают вам очень простой способ определить операцию, которая будет выполняться асинхронно, а затем сделать что-то еще, когда это будет сделано.

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

var task = new Task(clean_temp);
task.ContinueWith(update_global_variable);
task.ContinueWith(clean_temp);
task.Wait();

Фактический код будет не таким, но идея состоит в том, что вы определяете что-то, что нужно сделать (вызов clean_temp), затем вы определяете, что нужно сделать после выполнения первого задания (update_global_variable) и т.д. Вы можете объединить столько операций, сколько захотите.

Это, вероятно, будет намного чище, чем обработка потоков.

EDIT: На самом деле, вы, возможно, еще более упростили бы свой код, избавившись от глобальной переменной.

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

new Task(clean_temp, "C:\first temp folder")
   .ContinueWith(clean_temp, "C:\second folder")
   .Wait();

Гораздо чище и безопаснее :-)

  • 0
    Приложение является частью приложения Windows GUI. Он очищает временную папку и считает очищенные файлы в метке. Когда я написал что-то подобное, оно зависает: S Знаете ли вы, почему? var task = new Task (clean_temp); Task task2 = task.ContinueWith ((продолжение) => {temp_folder = APPDATA + "Local" + "\\" + "Temp \\";}); Task task3 = task.ContinueWith ((продолжение) => {clean_temp ();}); task.Wait ();
  • 0
    Ваш код довольно сложный (например, почему вы делаете вызовы Method.Invoke?), Поэтому сложно сказать точно. Вы должны использовать отладчик и посмотреть, что происходит. Кроме того, у вас есть try-catch, который ничего не делает в подвохе. Там тоже могут быть все виды ошибок.
Показать ещё 2 комментария
0

Если вы используете С# 5, попробуйте обернуть поток в задачу. Задачи предоставляют метод, называемый "ContinueWith", в котором вы можете снова вызвать свой поток. Или асинхронные вызовы с 'await'

Ещё вопросы

Сообщество Overcoder
Наверх
Меню