Обновление связанного списка со списком в кросс-потоке в C # - PullRequest
0 голосов
/ 20 июня 2011

Мой вопрос, если бы он был двухсторонним.Прежде всего, у меня есть список идентификаторов учеников, который постоянно добавляется и удаляется из программы.Как это сделать, чтобы в списке отображались только текущие элементы списка.Так, например, если у меня есть три идентификатора и я добавляю один, в списке автоматически отображается 4, и аналогично, если я уберу один элемент из списка, список автоматически сжимается на 1 запись.

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

Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 20 июня 2011

Для первой части вы можете использовать ObservableCollection вместо List.Во второй части, как вы знаете, вы не можете обновить элементы пользовательского интерфейса из потока backgroundworker, поэтому вам необходимо перенаправить логику обновления обратно в поток пользовательского интерфейса.Это может быть достигнуто с помощью Control.Invoke() / Control.BeginInvoke().Существует множество примеров для обеих тем, поэтому я просто позволю вам разобраться в деталях.

РЕДАКТИРОВАТЬ:

Для winforms вы можете заглянуть в BindingList<T>.Вот краткий пример, который я создал.

скажем, у вас есть

    class Car
    {
        public string CarName { get; set; }

        public override string ToString()
        {
            return CarName;
        }
    }

, вы можете создать BindingList вот так

    BindingList<Car> carList = new BindingList<Car>();

    private void Form1_Load(object sender, EventArgs e)
    {
        carList.Add(new Car{CarName = "Foo"});
        listBox1.DataSource = carList;
    }

добавить один элемент в список иустановите его как источник данных для списка.

Обновление списка из потока пользовательского интерфейса очень просто (обратите внимание, что добавление в список автоматически добавляет элемент в список.

    private void btnUIThread_Click(object sender, EventArgs e)
    {
        carList.Add(new Car{CarName = "BarFromUIThread"});
    }

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

private void btnBackgroundworker_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += bg_DoWork;
    bg.RunWorkerAsync();
}

private delegate void UpdateUIDelegate();
void bg_DoWork(object sender, DoWorkEventArgs e)
{
    listBox1.Invoke(new UpdateUIDelegate(UpdateListBox));
}

private void UpdateListBox()
{
    carList.Add(new Car { CarName = "BarFromBackgroundWorkerThread" });
}
0 голосов
/ 15 февраля 2018

Принятый ответ хорош, но BindingList не имеет метода Sort, поэтому мне пришлось использовать список и найти простое решение

В Windows Froms

В кросс-нити я просто использовал

// this = from on which listbox control is created.
this.Invoke(new Action(() => { SomeBindingSource.ResetBindings(false); }));

и ВОЙЛА

0 голосов
/ 20 июня 2011

я не совсем понимаю первую часть, что вы имеете в виду с текущими предметами?

Для второй части вы должны вызвать обновление вашего списка. Как это:

void updateListbox()
{
        if (listbox.Dispatcher.Thread != Thread.CurrentThread)
        {
            //invoke this function, because another thread is calling this function
            listbox.Dispatcher.Invoke(new Action(updateListbox));
        }
        else
        {
            //update listbox
        }
}
...