C # Вызов делегата из статического класса. - PullRequest
2 голосов
/ 22 октября 2011

У меня есть статический класс с именем Service, который запускает новый поток, чтобы сохранить сообщение прослушивания от другого процесса.В этом классе я управляю списком делегатов, который должен быть вызван при получении сообщения.Некоторые из методов этих делегатов должны выполняться в главном потоке.

Если бы я, например, создал угрозу в какой-либо форме, я мог бы просто сделать

this.Invoke(@delegate, new object[] { messageReceived });

Но я могуне делай этого, потому что я в статическом классе.Поэтому я попытался сделать так:

@delegate.Invoke(messageReceived);

Но это не работает, потому что не меняет подпроцесс, где выполняется метод (он выполняется из моей созданной угрозы, а не из основной).

Как мне это сделать?

Спасибо!

Ответы [ 4 ]

2 голосов
/ 22 октября 2011

Измените класс static, чтобы он принимал параметр.

Передайте переменную this в качестве параметра вашему классу static.

0 голосов
/ 22 октября 2011

Извините, я забыл это в своем вопросе. Я также хотел избежать использования классов System.Windows.Forms в моем статическом классе.

Самый простой способ, который я нашел, - это вызвать метод Invoke из объекта делегата (как я пытался раньше, но он не работал). И в методе делегата сделать это:

if (this.InvokeRequired)
    this.Invoke(MethodWhichDoesRealStuff, new object[] { message });
else
    MethodWhichDoesRealStuff(message);

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

0 голосов
/ 22 октября 2011

Ваша проблема может быть решена через SynchronizationContext. В двух словах, перехватить поток пользовательского интерфейса SynchronizationContext и использовать метод Post для публикации элемента в цикле сообщений графического интерфейса. Нет необходимости писать больше, так как вы можете найти отличную статью Здесь

0 голосов
/ 22 октября 2011

Почему вы не используете класс System.Threading.SynchronizationContext?Если вы собираетесь в будущем переехать в WPF, хорошо бы это узнать.Контекст синхронизации - это стандартный переносимый метод для работы с сообщениями между потоками.Существует версия для каждой системы ... из System.Web, форм Windows, wpf, а также пользовательского контекста синхронизации.

public static class MyClass
{
    public static void MyFunction(MyObject messageReceived )
    {
        // Call this stuff from non-gui thread.

        SynchronizationContext syncContext = SynchronizationContext.Current;
        syncContext.Send(MyMethod, param);

        // You can also use SyncContext.Post if you don't need to wait for completion.
        syncContext.Post(MyMethod, param);
    }

    private static void MyMethod(object state)
    {
        MyObject myObject = state as MyObject;
        ... do my stuff into the gui thread.
    }

    // Using anonymous delegates you can also have a return value using Send.
    public static int MyFunctionWithReturnValue(MyObject parameter)
    {
        int result = 0;
        SynchronizationContext.Current.Post(delegate (object p)
        {
            result = parameter.DoSomething()
        }, null);

        return result;
    }
}
...