Событие после темы isAlive - PullRequest
       1

Событие после темы isAlive

0 голосов
/ 16 ноября 2011

У меня есть форма с ярлыком с текстом «Загрузка».

label1.Text = "Loading...";

В Form.Load у меня есть новый поток, который что-то делает, скажем так.

void Form_Load(object sender, EventArgs args)
{
   Thread t = new Thread(run);
   t.Start();
}  

void run()
{
   for(int i = 0; i < 1000000; i++)
   {

   }
}

Я хочу изменить свойство label1.Text на "Завершено" после завершения потока "t". Но где и как изменить, я понятия не имею. Я изучаю темы. Нужно ли для этого создавать еще один поток, который постоянно проверяет свойство isAlive потока "t"?

Ответы [ 8 ]

3 голосов
/ 16 ноября 2011

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

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

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

2 голосов
/ 16 ноября 2011

У вас есть несколько решений.Если вы действительно хотите использовать класс Thread, вы можете вызвать метод Join, но это заблокирует поток пользовательского интерфейса, что не очень хорошо.Вы также можете вызвать метод Invoke вашей формы сразу после цикла «for», так что

void run()
{
    for (int i = 0; i < 100000000; i++)
    {
    }

    this.Invoke(new Action(() => this.label1.Text = "done"));
}

Метод invoke необходим, потому что вы находитесь в форме windows, а метод invoke выполнит ваш код наПоток пользовательского интерфейса.

Вместо использования класса Thread вы также можете взглянуть на Delegate.BeginInvoke и System.Threading.Tasks.Они оба более эффективны, так как объединяют потоки и обеспечивают обратный вызов для разделения вашего кода разрыва.

1 голос
/ 16 ноября 2011

Если вы хотите использовать ключевые слова async и await, предложенные Async CTP , то это крутое решение.

public async void Form_Load(object sender, EventArgs args)
{
  label1.Text = "Loading..."
  // Do some more stuff here if necessary.
  label1.Text = await Run();
}

private Task<string> Run()
{
  var tcs = new TaskCompletionSource<string>();
  Task.Factory.StartNew(
    () =>
    {
      for (int i = 0; i < 1000000; i++)
      {
      }
      tcs.SetResult("Finished");
    });
    return tcs.Task;
}
1 голос
/ 16 ноября 2011

Взгляните на TPL Task Parallel Library , которая поставляется с .NET4. Это дает вам возможность легко запустить фонового работника и определить другую задачу, которая будет запущена после завершения первой. Самое умное в том, что вторую задачу (как и любую другую) можно настроить для запуска в потоке пользовательского интерфейса, чтобы вам не приходилось переключаться в действии задач.

Как этот маленький образец здесь:

var task = new Task(() =>
{
    // DoSomething very long in background
}).ContinueWith(previousTask =>
    {
        // Do some action on UI thread
    },
    TaskScheduler.FromCurrentSynchronizationContext());

task.Start();
1 голос
/ 16 ноября 2011

легко

void run()
{
   for(int i = 0; i < 1000000; i++)
   {

   }

   Invoke(new MethodInvoker(delegate()
                                         {
                                             label1.Text = "finished";

                                         }));
}

или вы инициируете событие, но в таком простом случае это не так важно

1 голос
/ 16 ноября 2011

Нет, совсем нет.Вам необходимо отправить сообщение в поток пользовательского интерфейса (тот, который обрабатывает вашу форму).Прочтите это для некоторой информации: Как обновить графический интерфейс из другого потока в C #?

0 голосов
/ 16 ноября 2011

Передайте ссылку на ярлык или форму в свою ветку и используйте от Invoke до label1.Text="Completed"

0 голосов
/ 16 ноября 2011

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

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