找出表单实例化的原因 [英] Find out reason for form instancing

查看:26
本文介绍了找出表单实例化的原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,某种形式被实例化,我不知道为什么会发生这种情况.

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.

可以从这里得到吗?

Public Sub New()

    InitializeComponent()

或者有没有其他方法可以做到这一点?

Or is there any other way how I could do this?

这是调用堆栈:

推荐答案

这里的问题是由于您访问 frmMain默认实例来自后台线程.

The issue here was due to that you were accessing frmMain's default instance from a background thread.

VB.NET 包含每个表单的默认实例,因此您不必在每次想要打开新表单时都执行 Dim ... As New myForm.这种行为会让你缩短:

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()

到:

frmMain.Show()

虽然没有具体记录,但从我之前进行的测试看来,默认实例特定于当前线程.因此,如果您尝试从后台线程以任何方式访问默认表单实例,它将为 该特定线程创建一个新实例,因此与您在 UI 线程上使用的一个.

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.

最后,这将我们带到 WinForms 的黄金法则之一,LarsTech 提到:将所有 (G)UI 相关工作留在 (G)UI 线程上!

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!

如果您确实需要从后台线程访问 frmMain 的第一个实例,您应该创建一个返回该特定实例的 Shared 属性:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆