I have been wondering if the way I have implemented cancellation of a long-running import operation is correct.My questions are:Did I handle cancellation correctly?Is it ok to pass the cancelationTokenSource through the session like I do?Is it ok to use the session object like I did in my code?Here's the code (I have excluded the unnecessary parts):MVC controller which:Allows starting the operation with the Import()Retrieve import progress with ImportProgress()Cancel operation with CancelImport()public ViewResult Import(DataModel model){    var importSession = new ImportSessionWrapper(Session);    if (ModelState.IsValid)    {        var tokenSource = new CancellationTokenSource();        var token = tokenSource.Token;        importSession.ImportCancel = tokenSource;        Task.Factory.StartNew(() =>        {            try            {                Import fileImport = new Import(token);                fileImport.ProgressMade += (s, e) =>                {                    importSession.ImportProgress = e.Progress;                };                fileImport.DoImport();                importSession.ImportProgress = 100;                importSession.IsImportRunning = false;            }            catch (OperationCanceledException e)            {                importSession.HandleException(e.Message);            }       }, token).ContinueWith(        faultedTask =>            {                importSession.HandleException(faultedTask.Exception.InnerException.Message);            }, TaskContinuationOptions.OnlyOnFaulted);   }    return View(InteropData, model);}public ActionResult ImportProgress(){    var importSession = new ImportSessionWrapper(Session);    return Json(importSession.ReportImportProgress(), JsonRequestBehavior.AllowGet);}public void CancelImport(){    var sessionCancel = new ImportSessionWrapper(Session).ImportCancel;    if (sessionCancel != null)    {        sessionCancel.Cancel();        sessionCancel.Dispose();    }}Here is what the DoImport() looks like:public void DoImport(){    var records = ReadFile(importFilePath).ToList();    foreach (var record in records)    {        try        {                                    ProccesRecord(record);        }                            finally        {            int percentage = (int)(((double)records.IndexOf(record) / records.Count)*100);            ProgressMade?.Invoke(this, new ProgressEventArgs(percentage));        }        if (_cancelationToken.IsCancellationRequested)        {            _cancelationToken.ThrowIfCancellationRequested();        }                        }                        }And here is the SessionWrapper:public class ImportSessionWrapper{    private readonly HttpSessionStateBase _session;    private const string IMPORT_PROGRESS_NAME = importProgress;    private const string IMPORT_RUNNING = importRunning;    private const string IMPORT_ERROR = importError;    private const string IMPORT_CANCEL = importCancel;    public int ImportProgress    {        get { return (int)_session[IMPORT_PROGRESS_NAME]; }        set { _session[IMPORT_PROGRESS_NAME] = value; }    }    public bool IsImportRunning    {        get { return (bool)_session[IMPORT_RUNNING]; }        set { _session[IMPORT_RUNNING] = value; }    }    public string ImportErrors    {        get { return (string)_session[IMPORT_ERROR]; }        set { _session[IMPORT_ERROR] = value; }    }    public CancellationTokenSource ImportCancel    {        get { return (CancellationTokenSource)_session[IMPORT_CANCEL]; }        set { _session[IMPORT_CANCEL] = value; }    }    public ImportSessionWrapper(HttpSessionStateBase session)    {        _session = session;        if (!DoesSessionVariableExist(IMPORT_PROGRESS_NAME)) _session.Add(IMPORT_PROGRESS_NAME, 0);        if (!DoesSessionVariableExist(IMPORT_RUNNING)) _session.Add(IMPORT_RUNNING, false);        if (!DoesSessionVariableExist(IMPORT_ERROR)) _session.Add(IMPORT_ERROR, string.Empty);        if (!DoesSessionVariableExist(IMPORT_CANCEL)) _session.Add(IMPORT_CANCEL, null);    }            private bool DoesSessionVariableExist(string variableName)    {        return _session[variableName] != null;    }}
Cancelling long running operation in MVC4
c#;mvc;asp.net mvc 4;task parallel library