Выполнить метод/установить свойство в определенном потоке

68
3

Привет всем
Я отчасти новичок во всем этом многопоточном материале, поэтому, пожалуйста, извините меня, если я объясню это плохо:)


Скажем, у меня есть два класса:


class abc {
public string SomeProperty {
get { return something; }
set { /* This code has to execute in the main application thread */ }
}

public void SomeMethod() {
/* This code also has to execute in the main application thread */
}
}

class def {
abc obj;

public def() {
abc = new obj();
}

public void SomeMethod() {
abc.SomeProperty = "SomeValue";
abc.SomeMethod();
}
}


Проблема, с которой я столкнулась, заключается в том, что SomeProperty и SomeMethod выполняются в основном потоке приложения. Я пробовал:


abc.GetType().InvokeMember("SomeProperty", System.Reflection.BindingFlags.SetProperty, null, abc, new object[] { "SomeValue" });
abc.GetType().InvokeMember("SomeMethod", System.Reflection.BindingFlags.InvokeMethod, null, abc, null);

Однако код, который должен выполняться в основном потоке приложения, не выполняется в основном потоке приложения, даже используя InvokeMember (я так не думаю)
Я попытался выдавать текущее имя потока в коде и не выводит имя основного приложения.


Есть ли способ, которым я могу это сделать?
Если я объясню вещи плохо, просто дайте мне знать:)
Спасибо!

спросил(а) 2011-05-03T19:04:00+04:00 9 лет, 4 месяца назад
1
Решение
57

InvokeMember - это просто способ выполнения члена с использованием отражения. Это не имеет ничего общего с потоками.


Я подозреваю, что вы действительно ищете Control.Invoke или Dispatcher.Invoke (или неблокирующие BeginInvoke эквиваленты).

Разумеется, вам понадобится ссылка на соответствующий элемент управления или диспетчера, а затем создать соответствующий делегат для выполнения в другом потоке. Если вы ищете учебник по многопоточности Windows Forms (или WPF), вы должны найти множество примеров. (Мое сетевое соединение сейчас мусор, иначе я найду для вас достойный вариант.)


EDIT: теперь, когда вы очистили это консольное приложение, вам нужно будет обработать какую-то форму сообщения. Если нить никому не слушает сообщения, нет способа заставить его выполнить еще один бит кода. Я не использовал библиотеку, о которой вы говорили, но если она заставляет вас выполнять код в определенном потоке, тогда он должен предоставить некоторый эквивалент Control.Invoke и т.д.

ответил(а) 2011-05-03T19:08:00+04:00 9 лет, 4 месяца назад
70

Существуют различные способы сделать это, но мой предпочтительный подход выглядит следующим образом:


   protected void setTransactionButton(Boolean enabled)
{
(new Task(() =>
{
transcriptQuitButton.Enabled = enabled;
})).Start(uiScheduler);
}

В моем коде инициализации я назвал это:


uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

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


Существуют различные места, где вы можете найти для BeginInvoke, но если вы можете использовать анонимные функции, и одна статья здесь:


http://visualstudiomagazine.com/articles/2009/02/01/use-lambda-expressions-for-abstract-delegates.aspx

ответил(а) 2011-05-03T19:20:00+04:00 9 лет, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема