Загрузка WinForms на другие темы - PullRequest
0 голосов
/ 02 сентября 2011

Как и многие другие, мне нужно открыть WinForms в других потоках.Прочитав много разных статей, я вижу, что это невозможно, но мой вопрос: возможно ли это за один раз или есть ли способ достичь следующей цели?

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

Возможно ли это достичь каким-либо образом без использования функции WinForms в других потоках, что швы в настоящее время невозможны?

Заранее спасибо

РЕДАКТИРОВАТЬ

Всем вам, спасибо за хорошие статьи и советы, но я ошибался, не предоставив больше подробностей об одном из моих настоящихСВАО.В настоящее время я использую сторонний элемент управления, который позволяет мне открывать WinForms в контейнере MDI в качестве окон с вкладками (я использую Telerik.WinControls.UI.Docking.RadDock).Для этого основной поток пользовательского интерфейса, в котором размещается RadDock, должен быть проинформирован о недавно добавленных Winforms, чтобы иметь возможность добавлять их в список окон с вкладками.Это одна из вещей, которую я не вижу, как это можно сделать, потому что это будет включать в себя то, что одно из моих окон инструментов, созданное в другом потоке, может быть распределено и использовано в главном потоке.

Ответы [ 2 ]

2 голосов
/ 02 сентября 2011

Дело не в том, что вам нужно показывать свои WinForms в других потоках, скорее, вам нужно сделать работу внутри этих форм асинхронной и реализовать правильную поточно-ориентированную синхронизацию. У меня есть две статьи в блоге, которые относятся только к этому.

Оба предназначены для Windows Forms, и вы можете найти множество статей о том, как сделать WinForms асинхронными.

А например.

ToolWindowForm form = new ToolWindowForm()) {
form.Show();
// other code

Допустим, у вас есть это где-то в вашем коде, где вам нужно отобразить это окно инструментов, но для его загрузки требуется очень много времени, что блокирует выполнение остальной части кода. Ну, показ формы в другом потоке может быть одним из способов сделать это, и это очень возможно. Что может сделать это чрезвычайно сложным, так это то, что если вы обмениваетесь данными между формами и вам нужен доступ к элементам управления, вы столкнетесь с CrossThreadViolations и IllegalCrossThreadCalls. Проще и безопаснее просто сделать работу за каждой формой асинхронной.

Редактировать Если это необходимо, вы можете добавить приватных членов для хранения экземпляров форм, т. Е.

private Form m_MyToolForm = new Form();
private Form m_MyToolForm2 = new Form();

Тогда где-то в коде.

public void ShowToolForm() {
    Thread thread = new Thread(new ThreadStart(ShowToolFormAsync));
    thread.IsBackground = true;
    thread.Start();
}  

private void ShowToolFormAsync() {
    m_MyToolForm.ShowDialog(); // Blocks on this thread
}

Вы также можете использовать библиотеку параллельных задач, если вы используете .NET 4.

Task.Factory.StartNew(() => m_MyToolForm.ShowDialog());
0 голосов
/ 02 сентября 2011

Мне не кажется, что это было бы невозможно. Единственная большая проблема с созданием форм и обновлением элементов управления форм в разных потоках, в том, что вам понадобится потокобезопасный обратный вызов, в противном случае вы получите ошибки, из-за которых только родительский поток, создавший форму, сможет обновить графический интерфейс.

Дополнительная информация об этом поточно-ориентированном обратном вызове и материалах InvokeRequired, которые требуются для этой многопоточности, находится по адресу: http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.80%29.aspx

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