找出表单实例的原因 [英] Find out reason for form instancing
问题描述
在我的应用程序中,某种形式是实例化的,我不知道为什么发生这种情况。
因此,我想问一下,是否有可能检测到调用者加载/实例化表单。
是否可以从这里获取?
Public Sub New()
InitializeComponent()
<
编辑:
这是调用堆栈:
这个问题是由于您访问 frmMain
's 默认实例 。
VB.NET包含每个表单的默认实例,因此您不必执行 Dim。 ..作为新的myForm
每次你想打开一个新的表单。这个行为可以让你缩短:
$ p $ Dim mainForm As New frmMain
mainForm.Show()
到:
frmMain.Show()
虽然没有具体记录,但从以前进行我自己的测试看来,默认实例只针对当前线程 。因此,如果您尝试从后台线程访问默认表单实例 ,那么它将为创建特定线程的新实例,因此不会与你可以在UI线程中使用它。
最后,这将我们引入了WinForms的一个黄金法则,LarsTech提到了这一点: Leave all G)在(G)UI线程上与UI相关的工作!
如果你真的需要从后台线程访问你的第一个 frmMain
实例,你应该创建一个共享
属性,特定的实例:
Private Shared _instance As frmMain = Nothing
公共共享ReadOnly属性MainInstance由于frmMain
Get
返回_instance
End
End Property
$ b Private Sub frmMain_Load(sender As Object,e As EventArgs)处理MyBase.Load
如果frmMain._instance没有那么frmMain._instance = Me'设置主实例,如果不存在。
End Sub
然后从后台线程中你可以做到:
frmMain.MainInstance.DoSomething
In my application, a certain form is instanciated, and I have no idea why this happens.
I would therefore like to ask if it's possible to detect the "caller" that loads / instanciates the form.
Is it possible to get it from here?
Public Sub New()
InitializeComponent()
Or is there any other way how I could do this?
Edit: This is the callstack:
The issue here was due to that you were accessing frmMain
's default instance from a background thread.
VB.NET includes default instances of every form so that you don't have to do a Dim ... As New myForm
every time you want to open a new form. This behaviour will let you shorten:
Dim mainForm As New frmMain
mainForm.Show()
to:
frmMain.Show()
And although not specifically documented, from previously conducting my own test it appears that the default instance is specific to the current thread only. Thus if you try to access the default form instance in any way from a background thread it will create a new instance for that specific thread, and therefore not be the same as the one you're using on the UI thread.
In the end this brings us to one of the golden rules of WinForms, which LarsTech mentioned: Leave all (G)UI related work on the (G)UI thread!
If you really need to access your first instance of frmMain
from a background thread you should make a Shared
property that returns that specific instance:
Private Shared _instance As frmMain = Nothing
Public Shared ReadOnly Property MainInstance As frmMain
Get
Return _instance
End Get
End Property
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If frmMain._instance Is Nothing Then frmMain._instance = Me 'Setting the main instance if none exists.
End Sub
Then from a background thread you'll be able to do:
frmMain.MainInstance.DoSomething
这篇关于找出表单实例的原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!