I don't think using global variables is a good idea in this case. Here's how I would do it by adding cancellation logic to my AsyncOp class from a related question. This code also implements the IProgress pattern and throttles the ViewModel updates.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace Wpf_21611292
{
    /// <summary>
    /// Cancel and restarts an asynchronous operation
    /// </summary>
    public class AsyncOp<T>
    {
        readonly object _lock = new object();
        Task<T> _pendingTask = null;
        CancellationTokenSource _pendingCts = null;
        public Task<T> CurrentTask
        {
            get { lock (_lock) return _pendingTask; }
        }
        public bool IsPending
        {
            get { lock (_lock) return _pendingTask != null && !_pendingTask.IsCompleted; }
        }
        public bool IsCancellationRequested
        {
            get { lock (_lock) return _pendingCts != null && _pendingCts.IsCancellationRequested; }
        }
        public void Cancel()
        {
            lock (_lock)
            {
                if (_pendingTask != null && !_pendingTask.IsCompleted && !_pendingCts.IsCancellationRequested)
                    _pendingCts.Cancel();
            }
        }
        public Task<T> Run(
            Func<CancellationToken, Task<T>> routine,
            CancellationToken token = default,
            bool startAsync = false,
            bool continueAsync = false,
            TaskScheduler taskScheduler = null)
        {
            Task<T> previousTask = null;
            CancellationTokenSource previousCts = null;
            Task<T> thisTask = null;
            CancellationTokenSource thisCts = null;
            async Task<T> routineWrapper()
            {
                // await the old task
                if (previousTask != null)
                {
                    if (!previousTask.IsCompleted && !previousCts.IsCancellationRequested)
                    {
                        previousCts.Cancel();
                    }
                    try
                    {
                        await previousTask;
                    }
                    catch (Exception ex)
                    {
                        if (!(previousTask.IsCanceled || ex is OperationCanceledException))
                            throw;
                    }
                }
                // run and await this task
                return await routine(thisCts.Token);
            };
            Task<Task<T>> outerTask;
            lock (_lock)
            {
                previousTask = _pendingTask;
                previousCts = _pendingCts;
                thisCts = CancellationTokenSource.CreateLinkedTokenSource(token);
                outerTask = new Task<Task<T>>(
                    routineWrapper,
                    thisCts.Token,
                    continueAsync ?
                        TaskCreationOptions.RunContinuationsAsynchronously :
                        TaskCreationOptions.None);
                thisTask = outerTask.Unwrap();
                _pendingTask = thisTask;
                _pendingCts = thisCts;
            }
            var scheduler = taskScheduler;
            if (scheduler == null)
            {
                scheduler = SynchronizationContext.Current != null ?
                    TaskScheduler.FromCurrentSynchronizationContext() :
                    TaskScheduler.Default;
            }
            if (startAsync)
                outerTask.Start(scheduler);
            else
                outerTask.RunSynchronously(scheduler);
            return thisTask;
        }
    }
    /// <summary>
    /// ViewModel
    /// </summary>
    public class ViewModel : INotifyPropertyChanged
    {
        string _width;
        string _text;
        public string Width
        {
            get
            {
                return _width;
            }
            set
            {
                if (_width != value)
                {
                    _width = value;
                    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Width)));
                }
            }
        }
        public string Text
        {
            get
            {
                return _text;
            }
            set
            {
                if (_text != value)
                {
                    _text = value;
                    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    /// <summary>
    /// MainWindow
    /// </summary>
    public partial class MainWindow : Window
    {
        ViewModel _model = new ViewModel { Text = "Starting..." };
        AsyncOp<DBNull> _asyncOp = new AsyncOp<DBNull>();
        CancellationTokenSource _workCts = new CancellationTokenSource();
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = _model;
            this.Loaded += MainWindow_Loaded;
            this.SizeChanged += MainWindow_SizeChanged;
        }
        void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            _asyncOp.Run(WorkAsync, _workCts.Token);
        }
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            _asyncOp.Run(WorkAsync, _workCts.Token);
        }
        async Task<DBNull> WorkAsync(CancellationToken token)
        {
            const int limit = 200000000;
            var throttle = TimeSpan.FromMilliseconds(200);
            // update ViewModel's Width
            _model.Width = $"Width: {this.Width:#.##}";
            // update ViewModel's Text using IProgress pattern 
            // and throttling updates
            IProgress<int> progress = new Progress<int>(i =>
            {
                _model.Text = $"{(double)i / (limit - 1)* 100:0.}%";
            });
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            // do some CPU-intensive work
            await Task.Run(() =>
            {
                int i;
                for (i = 0; i < limit; i++)
                {
                    if (stopwatch.Elapsed > throttle)
                    {
                        progress.Report(i);
                        stopwatch.Restart();
                    }
                    if (token.IsCancellationRequested)
                        break;
                }
                progress.Report(i);
            }, token);
            return DBNull.Value;
        }
    }
}
XAML:
<Window x:Class="Wpf_21611292.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox Width="200" Height="30" Text="{Binding Path=Width}"/>
        <TextBox Width="200" Height="30" Text="{Binding Path=Text}"/>
    </StackPanel>
</Window>
It uses async/await, so if you target .NET 4.0, you'd need Microsoft.Bcl.Async and VS2012+. Alternatively, you can convert async/await to ContinueWith, which is a bit tedious, but always possible (that's more or less what the C# 5.0 compiler does behind the scene).