Измените выбранный индекс listBox через каждые 2 секунды, используя многопоточность - PullRequest
0 голосов
/ 13 января 2012

Я хочу изменять индекс выбранного индекса списка через каждые две секунды.

public Form1()
{
    InitializeComponent();
    listBox1.Items.Add("A");
    listBox1.Items.Add("B");
    listBox1.Items.Add("C");
    listBox1.Items.Add("D");
    listBox1.Items.Add("E");
    listBox1.Items.Add("F");
}

public void SelectEvery2Sec()
{
    System.Windows.Forms.Timer timer=new System.Windows.Forms.Timer();
    for (int i = 0; i < listBox1.Items.Count; i++)
    {
        timer.Start();
        listBox1.SelectedIndex = i;
        try
        {
            Thread.Sleep(2000);
        }
        catch{}

        if(i == listBox1.Items.Count -1)
            i = 0;
    }
}

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

Тогда я создам новый поток, но перекрестный доступ к потоку не допускается?

Ответы [ 4 ]

1 голос
/ 13 января 2012

Вы можете сделать это, используя Timer или BackgroundWorker.Для Timer установите Interval на 2 секунды.Для BackgroundWorker используйте RunWorkerAsync.

Для cross thread access issue используйте

public static class ControlExtensions
{
    public static void Invoke(this Control control, Action action)
    {
        if (control.InvokeRequired) control.Invoke(new MethodInvoker(action), null);
        else action.Invoke();
    }
}

Ваш старый код

listBox1.SelectedIndex = i;

станет

listBox1.Invoke(() => { listBox1.SelectedIndex = i; });
1 голос
/ 13 января 2012

Тогда я создам новую тему, но перекрестный доступ к теме не разрешен?

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

Несколько потоков не обязательно являются правильным решением в каждом случае. В этой ситуации управление таймером может быть проще - тот, который вам нужен, называется System.Windows.Forms.Timer.

Кроме того, вы можете использовать BackgroundWorker компонент . Все, что вам нужно сделать, это добавить его в форму во время разработки, и она позаботится обо всей грязной работе за вас. На странице MSDN есть отличный пример.

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

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

0 голосов
/ 13 января 2012

Вместо System.Windows.Forms.Timer используйте System.Threading.Timer. Это можно запустить в рабочем потоке.

Пусть обработчик события тайм-аута таймера вызывает функцию для изменения ListBox.SelectedItem, обязательно отметьте Invoke.Required при изменении выбранного элемента ListBox, так как вам нужно Invoke it.

0 голосов
/ 13 января 2012

Установите Interval вашего объекта таймера на 2000 мс, не переводите основной поток в спящий режим.

Вы можете обработать событие Timer Elapsed и обновить элемент управления.

UPDATE:

Чтобы сделать это двумя потоками, вызывайте событие во втором потоке каждые 2000 мс и связывайте с ним метод в вашей форме.В этом методе вы можете изменить элементы управления вашей формы.

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