我正在研究大型程序的功能。该功能需要调用可能计算密集的内容,并且可能需要很长时间。计算结果 - 从菜单项触发 - 将向当前图形添加一些内容。
还有很多其他选项可以改变当前的绘图。我不是在这里讨论它们。可以说,我希望我创建的“处理”是异步的,这样用户就不必在无响应的屏幕上凝视5分钟,认为程序已损坏,但能够点击其他地方...
所以:处理将是异步的,但最后,我将不得不绘制结果。
问题:我无法画画。
如果我运行我的代码,没有异步调用,当然一切都很完美。但是,如果我在BeginInvoke上调用处理,则会出现一些问题:
1)我调用的方法立即返回,所以在主线程中,如果我调用“draw”,结果就不会生成
2)如果我尝试将绘制放在EndInvoke之后,它就是在错误的线程上,所以myGraphics中的每个项目都说“参数无效”。
3)即使我在BeginInvoke之后保持调用(并以某种方式重新调用它),myGraphics仍然似乎已经转到另一个线程,我似乎有错误的信息。
为了获得最佳效果,我应该能够从线程返回,在EndInvoke之后以某种方式关闭它们......我只是不知道如何。
以下代码是一个片段,用于显示对“处理”的调用,然后是“绘制”。 (编辑:我已从代码中删除了更多内容,因此人们不会尝试输入代码并认为我的问题是基本的编译错误,比如输入错误或其他内容)
Public Sub mine(ByVal myGraphics As System.Drawing.Graphics)
a_call()
' use results from the finished call to process graphics
my_draw(myGraphics)
' if I add my_draw here, previous call only had BeginInvoke... more complicated to prevent my_draw...
' but it is not horrible to have first draw empty, and later draw correctly (if there is a way to trigger it - which I don't really have)
' The bigger problem is, myGraphics becomes defective (its VisibleClipbounds change, most points are not drawn anymore - or it becomes undefined)
' I don't understand why myGraphics changes or how to fix it
end sub
Public Sub a_call()
Dim c As New ADelegate(AddressOf A) ' which is the processing call
c.BeginInvoke(cb, Nothing)
End Sub
Private Sub A_Callback(ByVal ia As IAsyncResult)
...EndInvoke(ia)
A_Finish()
End Sub
Private Sub A_Finish()
If Me.InvokeRequired Then
Invoke(New ADelegate(AddressOf A_Finish))
Else
' call my_draw because I should be done with the Invoke ?
' If I add my_draw here, it is undefined
End Sub
当我说myGraphics被修改时......我真的看不出有什么可以改变它......
我一直在与理解线程和代表进行战斗......感谢任何帮助。
答案 0 :(得分:0)
我发现System.Drawing.Graphics不能被任何函数“拥有”,因此像球一样传递它是没有意义的。
由于它属于UI类 - 并且使用Paint事件正确创建 - 我的解决方案是将绘图过程与计算过程断开连接。
在绘制之前,我没有等待计算完成,而是在绘制新信息时单独绘制(由绘制事件触发),并且我异步计算 - 完全忽略UI中发生的任何事情。