Quantcast
Channel: Recent Threads — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 204402

async / await "finishes" running thread and resumes execution on main UI thread

$
0
0

I have created an asynchronous Task that the user can pause / resume. When the task is first run, it appears to run under a new thread (Thread.CurrentThread.ManagedThreadId == 5), which is separate from the main UI thread (Thread.CurrentThread.ManagedThreadId == 1). However, when the Task is paused (via an await method within the tasks main while() loop), the debug window shows the message: "Thread finished: #3". Then when the Task is resumed, all further execution occurs under the main UI thread.

Can someone explain exactly what is happening here and what I can do to make sure that my original thread is kept alive while my Task is paused?

Here is an example of my code:

//based on http://haukcode.wordpress.com/2013/01/29/high-precision-timer-in-netc/
public class HighPrecisionTimer : IDisposable
{
    Task _task;
    Task<Task> _taskWrapper;
    CancellationTokenSource _cancelSource;
    PauseTokenSource _pauseSource; //see http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx

    public bool IsPaused
    {
        get { return _pauseSource != null && _pauseSource.IsPaused; }
        private set
        {
            if (value)
            {
                _pauseSource = new PauseTokenSource();
            }
            else
            {
                _pauseSource.IsPaused = false;
            }
        }
    }

    public bool IsRunning
    {
        get
        {
            return !IsPaused && _taskWrapper != null && _taskWrapper.Status == TaskStatus.Running;
        }
    }

    public void Start()
    {
        if (IsPaused)
        {
            IsPaused = false;
        }
        else if (!IsRunning)
        {
            _cancelSource = new CancellationTokenSource();
            _taskWrapper = Task.Factory.StartNew(
                function: new Func<Task>(ExecuteAsync),
                cancellationToken: _cancelSource.Token,
                creationOptions: TaskCreationOptions.LongRunning,
                scheduler: TaskScheduler.Default);
            _task = _taskWrapper.Unwrap();
        }
    }

    public void Stop()
    {
        if (_cancelSource != null)
        {
            _cancelSource.Cancel();
        }
    }

    public void Pause()
    {
        IsPaused = !IsPaused;
    }

    async Task ExecuteAsync()
    {
        while (!_cancelSource.IsCancellationRequested)
        {
            if (_pauseSource != null && _pauseSource.IsPaused)
            {
                //this is the line that causes the current thread to "finish"...
                await _pauseSource.Token.WaitWhilePausedAsync();
            }

            // DO CUSTOM STUFF...
        }

        _cancelSource = null;
        _pauseSource = null;
    }

    public void Dispose()
    {
        if (IsRunning)
        {
            _cancelSource.Cancel();
        }
    }
}

Viewing all articles
Browse latest Browse all 204402

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>