所以,我最初有这段代码,其中调用者树中的父调用者是我的主窗口的加载函数。现在,每当我重新启动操作系统时,这给了我一个beginInvoke(你的Windows控件尚未初始化并尝试引用它)错误。许多人建议将它移动到显示的事件形式,如果加载了某个东西则添加一个布尔值,但这从未解决问题。因为我把头发拉出来,我最终只是删除了多线程。
'send broadcast on network
Dim tasksArr(1) As Task
Dim brand1SearchTask= Task(Of List(Of device)).Factory.StartNew(Function() getbrand1())
Dim brand2SearchTask= Task(Of List(Of device)).Factory.StartNew(Function() getbrand2())
Try
tasksArr(0) = brand1SearchTask
tasksArr(1) = brand2SearchTask
Task.WaitAll(tasksArr)
Catch ex As Exception
End Try
Try
Try
deviceList.AddRange(brand1SearchTask.Result())
Catch ex As Exception
End Try
deviceList.AddRange(brand2SearchTask.Result())
Catch ex As Exception
End Try
此代码位于名为NetworkSearch.FindDevices()的单独类中的函数内。它是从MainWindow_Load中的load函数调用的。
所以从我学到的主要问题是,在任务'.start或者开始调用它调用.Invoke,如果我的表单在那时没有初始化,它会从windows中抱怨。我的一个解决方案是创建一个单独的模块,然后创建一个New()形式的主窗口。这删除了错误,但该窗口中的任何其他表单(如单击按钮以启动另一个表单)也未初始化并给了我一个null异常。
我的问题:检查我是否在任务或线程环境中初始化然后等待进入我的线程的好方法是什么?如果这是一个控件,我会创建一个委托函数并编辑它,但这里并没有直接触及GUI。
我尝试了什么:
创建一个模块并从中创建一个New()主窗体,但是当从那里启动时,其余的表单都不是对象
- 移动到显示的主要形式(开始调用错误仍然发生)
- 添加了一个私有子My_application启动来处理带有My.Settings.Loadfinished布尔值的me.startup,但没有删除它。
- 添加了一个“mainwindow.invokerequired”检查,仅在运行时抱怨它需要说“我”而不是
答案 0 :(得分:0)
如果你想设计一个类,当它没有UI的直接知识时,能够专门在UI线程上执行代码,那么你有两个主要的选择:
在类SynchronizingObject
的类中声明ISynchronizeInvoke
属性。在内部,测试该属性是否为Nothing
,如果不是,请使用其InvokeRequired
属性和Invoke
/ BeginInvoke
方法。从外部,您可以为该属性分配表单或其他控件。这就是FileSystemWatcher
和Timers.Timer
类的工作方式。
在类SynchronizationContext
类中声明一个字段,并使用SynchroinizationContext.Current
对其进行初始化。如果您的类在UI线程上实例化,那么该字段将不是Nothing
,您可以使用其Send
/ Post
方法。