0

バックグラウンドでデータをダウンロードする wpf xbap アプリケーションがあります。アプリケーションの終了時に、ダウンロードを停止してキャッシュをフラッシュする必要があります。現在は次のように実装されています:
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 が呼び出され、loaderTask は null ではなく、Status は Running ですが、ts.Cancel() の後 IsCancellationRequested プロパティは変更されません (ここで説明されているように、タスク全体を while(true){..} 内にラップした後でも)。読み込みが停止しますが、自動 GC のおかげでのみ発生すると思います。私のフラッシュメソッドは実行されません。私は何が欠けていますか?psまた、別のスレッドで同時にタスクを実行するように機能をリファクタリングする必要がありますが、副作用を恐れています。どんな助けでも感謝します。前もって感謝します。

4

1 に答える 1

1

処理中に設定およびチェックしたいくつかの手動フラグを追加し、Start() の開始時に Stop() を呼び出して、動作が許容されるようにしました。

于 2012-10-23T14:21:43.227 に答える