2013-12-04 1 views
0

В wpf У меня есть два окна в отдельных потоках.
Из окна A 'в потоке A Я хотел бы запустить задачу в протекторах B окна B' и ждать возвращаемого значения в Thread A.
Предположим, что это возможно, но как?
Знаете ли вы, например, пример?Возможно ли передать задачу <T> (с возвращаемым значением) в существующий (уже запущенный) поток

+0

Почему вам нужно что ? Если вы хотите сделать массовое обновление пользовательского интерфейса (например, загрузите очень большую сетку), было бы лучше использовать привязку асинхронных данных или использовать виртуализацию данных. –

+0

Мы хотим, чтобы пользователь предоставил пользователю возможность открыть модель в отдельном окне и в разделительной нити или на вкладке. – Gerard

+1

И иметь кнопку/команду в основной форме обновить интерфейс на второй? Вы можете легко [отправить] (http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.post (v = vs.110) .aspx) вызов контекста syncrhonization Window B. Задача предпочтительна только в том случае, если у вас есть тяжелый подъем, который вы хотите запустить асинхронно. –

ответ

5

Несколько потоков пользовательского интерфейса WPF - довольно сложный сценарий.

Вы должны быть в состоянии сделать это, имея Thread B выставить задачи фабрики:

TaskFactory _taskFactory; 
public TaskFactory TaskFactory { get { return _taskFactory; } } 

В какой-то момент запуска Thread Б делать что-то вроде этого:

// Startup code running on Thread B 
_taskFactory = new TaskFactory(
    TaskScheduler.FromCurrentSynchronizationContext()); 

Тогда вы можете потребить фабрика из резьбы A, позволяющая Thread A (или любому) выполнять очередь на резьбу B:

await _threadB.TaskFactory.StartNew(() => 
{ 
    ... 
}); 
+0

Я попытаюсь разоблачить Taskfactory из класса Window. Тема является закрытым классом, или что вы имели в виду под именем '_threadB.TaskFactory'? – Gerard

+0

Я имел в виду любой объект, который вы используете, чтобы обернуть поток. –

0

Как я под Стоит, актуальная проблема заключается в том, как инициировать действие в окне B из окна A, когда оба окна работают в отдельных потоках.

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

Конечный результат совпадает с созданием задачи по потоку B. Обратный вызов будет выполняться в потоке B, но теперь вы избегаете работы по созданию и отправке задачи, и для этого требуется несколько меньше кода.

Чтобы сделать это аккуратно, вы можете сохранить ссылку на текущий контекст синхронизации при создании нового экземпляра окна B и использовать его в методе обертки в Windows, B:

public partial class WindowB : Window 
{ 
    private SynchronizationContext _context; 

    ... 

    protected override void OnActivated(EventArgs e) 
    { 
     base.OnActivated(e); 
     _context = SynchronizationContext.Current; 
    } 

    public void PostAction(string data) 
    { 
     _context.Post(ActualAction,data); 
    } 

    private void ActualAction(object state) 
    { 
     Title = state.ToString(); 

    } 
} 
Смежные вопросы