Как получить поток GUI winform?
у меня есть приложение winforms с несколькими потоками GUI. Я хочу, чтобы они могли получать доступ к объектам другого потока без того, чтобы отслеживать эту информацию отдельно.
есть ли функция в .NET, которую я могу передать элементу управления winforms или объекту window и вернуть поток? Или функцию в API я могу pinvoke для threadID?
(пожалуйста, никаких комментариев, говоря, что я должен сделать это по-другому... также речь идет не о кросс-нить оперативный.)
спасибо!
редактировать
для тех из вас, кто почему-то поверил моему выделенному курсивом тексту, поздравления,ты нанят!! вот в чем проблема:
" приложение рушится в дикой природе, полностью блокируя, то есть перестает отвечать. Очень прерывистый и пытается отладить его, кажется, никогда не происходит."
Так что же делать? Установите опцию в программе, которую пользователь может активировать под нашей направление, в котором из другого потока GUI в том же приложении, сделайте поток.прервать основной поток GUI, затем мы можем посмотреть стек вызовов в журнале ошибок. Виола, обнаружила невозможную для отладки ошибку менее чем за день. (Остановитесь, это не имело никакого отношения к злоупотреблению многопоточностью: -)
Я признаю, что я почти не спрашивал об этом, причина, по которой я это сделал, заключалась в том, что я мог видеть ссылку объекта на основную форму, но для ее нити не было. Я даю Крису Шейну ответ a / c, это быстро к сожалению, когда нить висит, я не смогу сделать вызов (он тоже будет висеть). Немного больше копания показало вызов API GetWindowThreadProcessId. Но это неуправляемый идентификатор потока, по-видимому, есть осложнения, превращающие его в управляемый идентификатор потока.
поэтому я укусил пулю и поместил глобальную ссылку на основной поток пользовательского интерфейса. Сначала я бы отправил его, но еще не написал.
4 ответов
Это должно сделать это, однако я согласен с другими плакатами, что это, вероятно, неправильно делать по другим причинам...
var thatWindowsThread = (Thread)(WhateverWindow.Invoke(()=>Thread.CurrentThread);
все элементы GUI в Windows Forms обычно выполняются в одном потоке. Я настоятельно рекомендую избегать попыток сделать это любым другим способом.
вы всегда можете маршалировать код в этот поток с помощью Control.Вызов или управление.BeginInvoke с любым контролем.
Если вы действительно хотите получить идентификатор потока (не уверен, что это будет..?), вы можете использовать:
int GetControlThreadId(Control control)
{
int threadId;
control.Invoke( new Action( () =>
{
threadId = Thread.CurrentThread.ManagedThreadId;
}));
return threadId;
}
Если ваш код находится не в форме или элементе управления, вы можете использовать
if (System.Windows.Forms.Form.ActiveForm.InvokeRequired)
{
System.Windows.Forms.Form.ActiveForm.Invoke(...);
}
WindowsFormsSynchronizationContext.Ток и в должности и отправить методы, из которых вы можете делегировать команду UI thread