Выполнить метод / установить свойство в определенном потоке - PullRequest
0 голосов
/ 03 мая 2011

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

Допустим, у меня есть два класса:

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 (я так не думаю), яЯ пытался вывести текущее имя потока в коде, и оно не выводило имя основного потока приложения.

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

Ответы [ 2 ]

2 голосов
/ 03 мая 2011

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

   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

1 голос
/ 03 мая 2011

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

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

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

РЕДАКТИРОВАТЬ: Теперь, когда вы ясно дали понять, что это консольное приложение, вам придется выработать какую-то форму прокачки сообщений. Если поток не прослушивает сообщений каким-либо образом, нет способа заставить его выполнить еще один бит кода. Я не использовал библиотеку, о которой вы говорили, - но если она заставляет вас выполнять код в определенном потоке, то она должна предоставлять некоторый эквивалент Control.Invoke и т. Д.

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