LoadArtifactsBgOperation StartLoadArtifacts()
        {
            var op = new LoadArtifactsBgOperation { Cts = new CancellationTokenSource() };

            op.Task = Task.Factory.StartNew(() => {
                try
                {
                    return LoadArtifacts(op.Cts.Token);
                }
                finally
                {
                    op.Cts.Dispose();
                    op.Cts = null;
                }
            }, op.Cts.Token);

            simplifiedBackgroundOperation.Track(op.Task, "Refreshing...");

            return op;
        }
        LoadArtifactsBgOperation StartOrPickupLoadArtifacts()
        {
            // pickup progressed background operation
            if (_firstArtifactsLoad != null)
            {
                var op = _firstArtifactsLoad;
                _firstArtifactsLoad = null;

                if (!op.Task.IsCompleted)
                    return op;
            }

            return StartLoadArtifacts();
        }
        void RallyTool_Load(object sender, EventArgs e)
        {
            Text = Text + " (ver. " + NewVersionControl.ProductVersion + ")";

            if(string.IsNullOrWhiteSpace(Settings.Default.RallyUser))
            {
                if (new RallySettings().ShowDialog() == DialogResult.OK)
                {
                    // force refresh query
                    Settings.Default.RallyQuery = null;
                    EnsureQueryValid();
                }
            }

            // start loading artifacts on every form opening.
            // sometitme it will be in bg, sometime in fg
            _firstArtifactsLoad = StartLoadArtifacts();

            var lastUpdate = DateTimeOffset.MinValue;
            var artifacts = LoadCachedArtifacts(ref lastUpdate);

            if (artifacts != null)
            {
                SetArtifactsList(artifacts, lastUpdate);

                // and force update list if fingerprints does not match
                _firstArtifactsLoad
                    .Task
                    .ContinueWith(t => {
                            var freshArtifacts = t.Result;
                            if(CalcFingerprint(_filteredIssues.Select(i => i.WorkItem)) != CalcFingerprint(freshArtifacts))
                            {
                                SetArtifactsList(freshArtifacts, DateTimeOffset.Now);
                            }
                        },
                        _firstArtifactsLoad.Cts.Token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext()
                    )
                ;
            }
            else
            {
                // force open 'wait for refresh' dialog
                RefreshArtifactsList();
            }
        }