Reputation: 1831
I have a wpf xbap application that downloads some data in background. There is a need to stop downloading and flush cache on application exit. Now it is implemented as follows :
App.xaml :
<Application Exit="ApplicationExit">
App.xaml.cs :
private void ApplicationExit(object sender, ExitEventArgs e)
{
BackgroundImageLoader.Instance.Stop(); // target
ViewModelLocator.Cleanup();
FileCacheHelpers.FlushTemporaryFolder();
}
BackgroundImageLoader.cs :
// Thread-safe singleton
public sealed class BackgroundImageLoader
{
private static volatile BackgroundImageLoader _instance;
private static readonly object SyncRoot = new object();
private BackgroundImageLoader() { }
public static BackgroundImageLoader Instance
{
get
{
if (_instance == null)
{
lock (SyncRoot)
{
if (_instance == null)
_instance = new BackgroundImageLoader();
}
}
return _instance;
}
}
// other properties, omitted for conciseness
private Task loaderTask;
private CancellationTokenSource ts;
public void Start()
{
ts = new CancellationTokenSource();
var ct = ts.Token;
loaderTask = Task.Factory.StartNew(() =>
{
// TaskList is an array of tasks that cannot be canceled
// if they were executed, so i want to actually cancel the
// whole pool after last non-canceled operation was ended
foreach (var task in TasksList)
{
if (ct.IsCancellationRequested)
{
Debug.WriteLine("[BackgroundImageLoader] Cancel requested");
// wait for last operation to finish
Thread.Sleep(3000);
FileCacheHelpers.FlushTemporaryFolder();
break;
}
task.DoSomeHeavyWorkHere();
}
}, ct);
}
public void Stop()
{
if (loaderTask != null)
{
if (loaderTask.Status == TaskStatus.Running)
{
ts.Cancel();
}
}
}
}
Stop is called, loaderTask is not null and Status is Running, but after ts.Cancel() IsCancellationRequested property is not changed (even after wrapping the whole task inside while(true){..} as described here). Loading stops, but i guess it happens only thanks to automatic GC. My flush method is not executed. What am i missing? p.s. Also i need to refactor the functionality to run tasks in separate threads simultaniously, but afraid of side effects. Any help appreciated. Thanks in advance.
Upvotes: 0
Views: 491
Reputation: 1831
Added few manual flags which I set and check during processing and call to Stop() at the beginning of Start() so behaviour is acceptable.
Upvotes: 1