Не может управлять ObservableCollection во много потоках

Отвечая на мой собственный вопрос, вот лучшее решение, которое я нашел до сих пор. Классы A и B (которые представляют элементы GUI) наследуются от класса Base, который содержит статический указатель на объект parent . Один и тот же родительский объект предоставляет друзьям доступ к A и B, чтобы они могли обращаться к открытым функциям друг друга по мере необходимости. Преимущество этой системы в том, что вы можете очень легко создавать и связывать новые объекты GUI (C, D ...): все, что вам нужно, это наследовать от Base и обновлять дружбу в Parent.

Вот код:

class Parent; // forward declaration for Base class static variable

class Base       // class Base is just there to hold a pointer to the parent object for its derived classes
{
private:
    static Parent * parent_ptr;
public:
    Parent* getParent() const { return parent_ptr; }
};

class A : public Base
{
public:
    int a_int;
    A(const int a) : a_int(a) {}
    void someFunction() const { std::cout << a_int; }
};

class B : public Base
{
public:
    int b_int;
    B(const int b) : b_int(b) { doSomethingToA(); }  // Initiating this from the constructor, but really I would want to wait for a Listener
    void doSomethingToA() const;
};

class Parent
{
private:
    A a = { 2 };
    B b = { 3 };
    friend class A;
    friend class B;
} parent;

Parent* Base::parent_ptr = &parent;

void B::doSomethingToA() const  { getParent()->a.someFunction(); }
7
задан user25749 9 October 2008 в 12:40
поделиться

2 ответа

Используя ссылку, предоставленную Кентом, Вы могли использовать следующий код для изменения набора через потоки:

while (!Monitor.TryEnter(_lock, 10))
{
   DoEvents();
}

try
{
   //modify collection
}
finally
{
   Monitor.Exit(_lock);
}

Если однако Вы просто надеетесь изменять набор на своем исходном потоке, можно попытаться использовать обратный вызов для потока UI. Я обычно делаю что-то вроде этого:

this.Dispatcher.Invoke(new MyDelegate((myParam) =>
{
  this.MyCollection.Add(myParam);
}), state);
7
ответ дан 6 December 2019 в 14:11
поделиться

Вы в основном добрались для Вызова или BeginInvoke к потоку UI, чтобы сделать те операции.

Public Delegate Sub AddItemDelegate(ByVal item As T)

Public Sub AddItem(ByVal item As T)
    If Application.Current.Dispatcher.CheckAccess() Then
        Me.Add(item)
    Else
        Application.Current.Dispatcher.Invoke(Threading.DispatcherPriority.Normal, New AddItemDelegate(AddressOf AddItem), item)
    End If
End Sub
3
ответ дан 6 December 2019 в 14:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: