Fas*_*tAl 7 .net c# vb.net winapi
我有一个带有多个GUI线程的winforms应用程序.我希望他们能够访问彼此的线程对象,而无需单独跟踪这些信息.
.NET中是否有一个函数可以提供winforms控件或窗口对象,然后返回线程?或者API中的函数我可以为threadID设置pinv?
(请不要发表评论说我应该采取另一种方式......这也不是关于跨线程窗口操作.)
谢谢!
对于那些因某种原因相信我的斜体文字,祝贺你的人,你被录用了!! 这是问题所在:
"应用程序通过完全锁定而崩溃,即它停止响应.非常间歇性,并试图调试它,似乎永远不会发生."
那怎么办?在用户可以在我们的指导下激活的程序中安装一个选项,从同一应用程序中的另一个GUI线程,在主GUI线程上执行thread.abort,然后我们可以在错误日志中查看调用堆栈.Viola,在不到一天的时间内发现无法调试错误.(现在停止,它与滥用多线程无关:-)
我承认我几乎没有问这个,我做的原因是我可以看到主要表单的对象引用,但是它的线程没有.我给Chris Shain答案a/c这是一个快速的方法,不幸的是当线程挂起时,我将无法进行调用(它也会挂起).稍微挖掘一下,揭示了GetWindowThreadProcessId API调用.但它是一个非托管的线程ID,显然有并发症将其转换为托管线程ID.
所以我咬了一口子,并对主UI线程进行了全局引用.本来会发布它,但尚未写出来.
现在,如果你原谅VB ......
Public GUIThread As Threading.Thread
Sub Main()
'' // Create app main window
ShellForm = New frmShell
'' // Save main GUI Thread for abort routine
GUIThread = Threading.Thread.CurrentThread
If GetSetting("MyApp", "Testing", "CrashDebug", "False") = "True" Then
'' // DO NOT run the pgm. like this normally - with try/catch around
'' // Application.Run - or uncaught errors will kill the whole app!!!
Try
'' // This is the other of the ‘Multiple GUI threads’ I talked
'' // about in the Orig Post.
Dim t As New Threading.Thread(AddressOf StartCrashDebug)
t.Start()
Application.Run(ShellForm)
Catch ex As Exception
'' // This error routine passes errors off to another thread which
'' // logs them (and also shows messages)
MyLogError(ex, "CrashDebug - Main Window blew up")
End Try
Else
'' // Normal mode - uncaught errors will get caught by UnhandledException,
'' // logged, and Winforms will keep the GUI alive (since we _do_ care
'' // more about users than computers right ;-)
Application.Run(ShellForm)
End If
End Sub
Sub StartCrashDebug()
Dim f As New frmCrashFinder
'' // Starting a window like this on a separate thread makes it ‘Another
'' // GUI thread’ for winforms, by design
Application.Run(f)
End Sub
Run Code Online (Sandbox Code Playgroud)
Public Class frmCrashFinder
Inherits Windows.Form
Private Sub Abort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Abort.Click
GUIThread.Abort()
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
Ree*_*sey 12
Windows窗体中的所有GUI元素通常在单个线程上完成.我强烈建议避免尝试以任何其他方式执行此操作.
您可以使用Control.Invoke或Control.BeginInvoke与任何Control一起编组代码到该线程.
如果你真的想得到线程的ID(不确定这将是什么用途??),你可以使用:
int GetControlThreadId(Control control)
{
int threadId;
control.Invoke( new Action( () =>
{
threadId = Thread.CurrentThread.ManagedThreadId;
}));
return threadId;
}
Run Code Online (Sandbox Code Playgroud)
这应该这样做,但我同意其他海报,这可能是出于其他原因的错误做法......
var thatWindowsThread = (Thread)(WhateverWindow.Invoke(()=>Thread.CurrentThread);
Run Code Online (Sandbox Code Playgroud)
如果您的代码不在窗体或控件中,则可以使用
if (System.Windows.Forms.Form.ActiveForm.InvokeRequired)
{
System.Windows.Forms.Form.ActiveForm.Invoke(...);
}
Run Code Online (Sandbox Code Playgroud)