HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Cancellable UI loader

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
cancellableloaderstackoverflow

Problem

I'm playing with async/await, but I have yet to discover a standard method to safely cancel an intensive task. I have tested the following, and it works exactly as intended, though I remain unsure if a standard method exists.

```
abstract class PageLoader where TPage : Page
{
private TPage page;
private Task loader;
private volatile bool mode;
private volatile int token;

public PageLoader(TPage page)
{
if (page == null)
{
throw new ArgumentNullException("page");
}

this.page = page;
this.mode = true;
}

protected TPage Page => page;
protected bool Mode => mode;

public void Load(TElement[] items)
{
if (!page.Dispatcher.HasThreadAccess)
{
throw new InvalidOperationException("The current thread is not authorized.");
}

if (loader != null)
{
throw new InvalidOperationException("The loader requires reset.");
}

if (items == null)
{
throw new ArgumentNullException("items");
}

int value = token;

mode = true;
(loader = new Task(() => AutoLoad(value, items))).Start();
}

public async Task Set(bool retainMode)
{
if (!page.Dispatcher.HasThreadAccess)
{
throw new InvalidOperationException("The current thread is not authorized.");
}

if (mode)
{
mode = false;

if (loader != null)
{
await loader;
loader = null;
token++;
}

if (retainMode)
{
mode = true;
}

return true;
}

return false;
}

protected void Commit(Entry entry)
{
if (entry == null)
{
throw new ArgumentNullException("entry");
}

DispatchedHandler handler = () =>
{
if (entry.Token

Solution

You should be using a CancellationToken, which can be generated like:

CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;


Pass this token to the method you wish to potentially cancel and keep a reference outside the method. Then, from the calling method you can check token.IsCancellationRequested at periodic intervals and return, or if you wish to throw, you can call token.ThrowIfCancellationRequested(). To signal a cancellation, you call source.Cancel(), which propagates through to the token and signals a cancellation request. You can also set it up to automatically cancel after a certain amount of time when you create the CancellationTokenSource.

Code Snippets

CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;

Context

StackExchange Code Review Q#118577, answer score: 6

Revisions (0)

No revisions yet.