私はタイマーに常に問題があります。10 個のタイマーを問題なく同時に実行できる場合もあれば、空のメソッドをターゲットにしている 2 個のタイマーですべてがフリーズする場合もあります。
転換点は、バックグラウンドよりも高い優先度を持つ 1 つのクラスで 1 つのタイマーを実行することさえできないことです。タイマーは、キャンバスの周りでユーザー要素をドラッグできるようにするために使用され、その優先度をレンダリングに設定すると、バックグラウンドよりもはるかにスムーズになります。
ただし、タイマーが行うことのリストに新しいサブを追加すると、バックグラウンドよりも高い優先度でフリーズするようになりました。私が追加したサブルーチンは、要素間の位置スナップを計算することになっています。重い義務はなく、要素ごとにいくつかの計算が必要です。それが違いを生む場合、サブは(キャンバスクラスで)呼び出されたクラスの外に存在します。
私が使用しているタイマー クラスは windows.threading.dispatchtimer です。私がそれについて赤くしたことから、それはそれが操作する必要があるので、私が必要とするものであるメインUIスレッドから実行されます。ただし、はるかに強力なワークロードであっても、winformのタイマーでそのような問題はありませんでした。
関連するもののいくつかのコードスニペットを次に示します。
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