2008-12-04 3 views
1

У меня есть следующая проблема: многопоточное приложение WPF, представление представления представления представления модели. Презентаторы и представления, которые принадлежат друг другу, создаются в отдельном потоке и получают отдельный диспетчер. Теперь кто-то вызывает из другого потока метод на презентаторе. Я перехватываю вызов, и теперь возникает проблема: если вызов поступает из того же потока, что и ведущий, я хочу продолжить вызов, иначе вызовите вызов Dispatcherthread, так что мне не нужно заботиться о Пользовательский интерфейс. Я уже читал об использовании SynchronizationContext, но, похоже, это не работает для меня, потому что если вызывающий поток не является потоком пользовательского интерфейса, я не могу сравнивать два контекста. Какое возможное, работающее и элегантное решение?Как передать вызов метода другому потоку?

ответ

3
if(presenterDispatcherObject.CheckAccess()) 
    Doit(); 
else 
    presenterDispatcherObject.BeginInvoke(DispatcherPriority.Normal,() => DoIt()); 
0

Если вы хотите, чтобы вызов диспетчера блокировал (ожидание возврата), я бы использовал Invoke вместо BeginInvoke. Это подражало бы скорее поведению, фактически вызывающему функцию напрямую. Вызывать блоки, вызывающие поток, пока функция не будет финиширована (скорее, как Win32 SendMessage). BeginInvoke просто отправляет сообщения и возвращает их, не дожидаясь возврата функции (например, Win32 PostMessage).

CheckAccess работает медленно. Я бы ограничил CheckAccess, оставив вызовы менее частыми в разных потоках.

public delegate bool MyFuncHandler(object arg); 

bool ThreadedMyFunc(object arg) 
{ 
    //... 

    bool result; 

    //... 

    // use dispatcher passed in, I would pass into the contructor of your class 
    if (dispatcher.CheckAccess()) 
    { 
     result = MyFunc(arg); 
    } 
    else 
    { 
     result = dispatcher.Invoke(new MyFuncHandler(MyFunc), arg); 
    } 

    return result; 
} 

bool MyFunc(object arg) 
{ 
    //... 
} 
Смежные вопросы