1

私はタイマーに常に問題があります。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
4

0 に答える 0