我经常遇到计时器问题。有时我可以毫无问题地同时运行 10 个计时器,有时 2 个针对空方法的计时器足以让一切冻结。
引爆点是,现在我什至不能在一个优先级高于背景的类上运行单个计时器。计时器用于启用在画布周围拖动用户元素并将其优先级设置为渲染使其比在背景中更平滑。
当我在计时器要做的事情列表中添加一个新的子时,它现在冻结在任何高于背景的优先级上。我添加的 sub 应该计算元素之间的位置捕捉,没有什么繁重的任务,每个元素进行少量计算。如果这有所不同,则子确实位于调用它的类之外(在画布类中)。
我正在使用的计时器类是 windows.threading.dispatchtimer。从我对它的红色来看,它运行了我需要的主 ui 线程,因为这就是它需要操作的东西。尽管如此,我在winforms中的计时器没有这样的麻烦,即使工作量更大,那有什么用呢?
以下是相关内容的一些代码片段:
floater class:
Private WithEvents transformTimer As New Windows.Threading.DispatcherTimer(Windows.Threading.DispatcherPriority.Render, Dispatcher) With {.Interval = New TimeSpan(166)}
Then there is a sub that handles click on the floater object and enabled the timer
then there is a sub that handles the timer ticks, checks for mouse buttons and position to make the necessary adjustments and calls the following sub
Public Sub place(r As DoubleRect)
If mainTitle.snap Then
mouseSnap = wParent.getMoveSnap(Me)
wParent.writeAll(mouseSnap.ToString)
sRect.x = mouseSnap.X
sRect.y = mouseSnap.Y
End If
If cRect.x <> r.x Then Canvas.SetLeft(Me, r.x + sRect.x)
If cRect.y <> r.y Then Canvas.SetTop(Me, r.y + sRect.y)
If cRect.w <> r.w Then Me.Width = r.w + sRect.w
If cRect.h <> r.h Then Me.Height = r.h + sRect.h
cRect = r.clone
vRect = rActualToVisible(cRect)
End Sub
DoubleRect is a basic rectangle class with doubles for location and size
and then there is the sub that makes the whole thing freeze in combination with the timer priority
Public Function getMoveSnap(rWindow As uiWindow) As Point
Dim vRect As DoubleRect = rWindow.vRect
Dim vRect2 As DoubleRect
Dim dir As sDirections
Dim amt As Double
For i = 0 To rWindows.Count - 1
If Not rWindows(i).Equals(rWindow) Then
vRect2 = rWindows(i).vRect
dir = vRect.sDirection(vRect2)
If dir = sDirections.N Then
amt = vRect.y - vRect2.y2
If amt < snapDistance Then Return New Point(0, -amt)
ElseIf dir = sDirections.S Then
amt = vRect2.y - vRect.y2
If amt < snapDistance Then Return New Point(0, amt)
ElseIf dir = sDirections.W Then
amt = vRect.x - vRect2.x2
If amt < snapDistance Then Return New Point(-amt, 0)
ElseIf dir = sDirections.E Then
amt = vRect2.x - vRect.x2
If amt < snapDistance Then Return New Point(amt, 0)
Else
Return New Point()
End If
End If
Next
End Function
sDirections is an enum of N S W E and invalid(X) directions to snap in
sDirection is a method of doublerect that does a long chain of "if x > r.x then blah blah" to determine the direction