Skip to main content

FrameThread class

Namespace: Arlecchino · Assembly: Arlecchino.Core

Which thread draws, claimed by the frame loop as it starts. Views, widgets, atoms and the surface are written without locks, and this is what turns that convention into something the framework checks.

public static class FrameThread

Properties

MemberSummary
HasPendingWhether anything posted is still waiting to run.
IsCurrentWhether the calling thread is the one drawing, or nothing has claimed drawing yet.

Methods

MemberSummary
Claim(Action)Claims the calling thread as the one that draws. An application running the frame loop itself calls this too, so the checks know which thread is meant.
DiscardPending()Drops what was posted and never run. An application going away calls it, and so does a test host as it is disposed, so that work left over by one does not run inside the next.
Post(Action)Hands work to the drawing thread, to run just before the next frame in the order it was posted. With no thread drawing it waits for FrameThread.RunPending.
Post(Func<Task>)Hands asynchronous work to the drawing thread. It starts there, and every await inside it that was not told otherwise comes back there, so what it reads and writes is what a frame draws.
RunPending(Action<Exception>)Runs what was posted before this call. Called by the frame loop; work posted by that work waits for the next frame, so an action that posts itself is a loop you can leave.
Verify(string)Throws unless the caller is on the drawing thread. This is what a member that changes what a frame draws calls before changing anything.

Properties in detail

HasPending

public static bool HasPending { get; }

Whether anything posted is still waiting to run.

Type bool

IsCurrent

public static bool IsCurrent { get; }

Whether the calling thread is the one drawing, or nothing has claimed drawing yet.

Type bool

Methods in detail

Claim(Action)

public static IDisposable Claim(Action? wake = null);

Claims the calling thread as the one that draws. An application running the frame loop itself calls this too, so the checks know which thread is meant.

Parameters

NameTypeDescription
wakeActionAsks for a frame, called whenever something is posted. The frame loop passes its repaint signal, so posted work is drawn without the caller having to ask.

Returns IDisposable — A scope that gives the claim up again. Giving up the last claim drops what is still posted, since no frame is left for it to run before.

DiscardPending()

public static void DiscardPending();

Drops what was posted and never run. An application going away calls it, and so does a test host as it is disposed, so that work left over by one does not run inside the next.

Post(Action)

public static void Post(Action action);

Hands work to the drawing thread, to run just before the next frame in the order it was posted. With no thread drawing it waits for FrameThread.RunPending.

Parameters

NameTypeDescription
actionActionWhat to run where it is safe to change what a frame draws.

Post(Func<Task>)

public static void Post(Func<Task> work);

Hands asynchronous work to the drawing thread. It starts there, and every await inside it that was not told otherwise comes back there, so what it reads and writes is what a frame draws.

Parameters

NameTypeDescription
workFunc<TResult><Task>What to run. Whatever it throws, before an await or after one, reaches the frame loop the way a posted action's failure does; being canceled is not a failure.

RunPending(Action<Exception>)

public static void RunPending(Action<Exception> onError);

Runs what was posted before this call. Called by the frame loop; work posted by that work waits for the next frame, so an action that posts itself is a loop you can leave.

Parameters

NameTypeDescription
onErrorAction<T><Exception>What to do with an action that threw.

Verify(string)

public static void Verify(string member);

Throws unless the caller is on the drawing thread. This is what a member that changes what a frame draws calls before changing anything.

Parameters

NameTypeDescription
memberstringWhat was called, named in the message.

Exceptions

TypeThrown when
InvalidOperationExceptionThe caller is on another thread.