2016-11-04 4 views
0

私のコードに問題があります。私はメインフォームを持つグラフィックアプリを作成しています。私がボタンをクリックすると、いくつかのファイルをエクスポートしながら進行状況バーを表示する新しいフォームを作成します。私の問題は、プログレスバーを使ってフォームを閉じようとするときに始まります。その理由は、どのエクスポートファイルが終了しないのかということです。閉じるフォームのときにスレッド内で実行中のメソッドを停止する

新しいフォームでは、エクスポートの進行状況を確認してプログレスバーを埋めるメソッドを実行します。このメソッドは1秒ごとに実行されます。エクスポートするには新しいスレッドを作成し、このスレッドはエクスポートメソッドを実行します。

エクスポートが完了したら、フォームとスレッドは正しく終了しますが、フォームを閉じることによって操作を強制停止すると、エクスポートされているスレッドはエクスポートが終了するまで、またはメインフォームを閉じるまで停止しません。

どうすればそのスレッドを停止できますか?

これは私のコードです:

public Form3(File file, string output, string inputFile) 
    { 
     InitializeComponent(); 
     this.file = file; 
     this.output = output; 
     this.inputFile = inputFile; 
     progressLabel.Location = new Point(textProgress.Right, progressLabel.Top); 
     thread = new Thread((ThreadStart)delegate { Exporter.ExportToFile(this.file, this.output, this.inputFile); }); 
     thread.IsBackground = true; 
     thread.Start(); 

     TimerControl(); 


    } 

    private void TimerControl() 
    { 
     System.Windows.Forms.Timer t = new System.Windows.Forms.Timer(); 
     t.Tick += new EventHandler(GetProgress); 
     t.Interval = 1000; // in miliseconds 
     t.Start();  

    } 

    private void GetProgress(object sender, EventArgs myEventArgs) 
    { 
     int x = Exporter.GetProgress(); 
     progressBar.Maximum = 100; 
     if (!Exporter.stop) 
     { 
      progressBar.Value = x; 
      progressLabel.Text = x.ToString() + "%"; 
     } 
     else 
     { 

      this.Close(); 

     } 
    } 
+0

これを正しく行うには、Exporter.ExportToFile()にキャンセルのサポートを追加する必要があります –

+0

残念ですが(幾分)効果的です:あなたの 'Closing'イベント'thread.Abort()'を呼び出す - もちろん、他の方法も好きです。 –

+0

それはひどいアドバイスです。 ['決してThread.Abort()を呼び出さない]](http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort)。 –

答えて

0

事はここに理解するために:「ファイルへのエクスポート」(Exporter.ExportToFile)...が、おそらくを停止するように書かれていないことを実行されるコードを。

つまり、そのコンポーネントを強化したいとします。このようなコンテキストで実際に使用する場合は、エクスポータに別のメソッドを追加することをお勧めします。 「AbortExport」などのようなものです。 (だけではなく、例えば、基礎となるスレッドを殺す - あなたは、輸出によって作成されたファイルは、例えば削除されることを保証することがあります。そして、すべての関連するリソースは、適切なクリーンアップを見ている)

0

使用しない理由代わりにタスク?

OperationCanceledExceptionをスローし、それをキャンセルが要求されたトークンを渡すことによってhttps://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

からの引用。これを行う好ましい方法は、ThrowIfCancellationRequestedメソッドを使用することです。このようにして取り消されたタスクは、キャンセルされた状態に遷移します。この状態で、呼び出しコードはタスクが取り消し要求に応答したことを確認できます。

引用https://msdn.microsoft.com/en-us/library/dd997364(v=vs.110).aspx

から協調キャンセルモデルを実装するための一般的なパターンは:

  • を管理し、個々のキャンセルトークンにキャンセル通知を送信CancellationTokenSourceオブジェクトをインスタンス化。

  • CancellationTokenSource.Tokenプロパティによって返されたトークンを、キャンセルをリッスンする各タスクまたはスレッドに渡します。

  • キャンセルに応答する各タスクまたはスレッドのメカニズムを提供します。

  • CancellationTokenSource.Cancelメソッドを呼び出してキャンセルの通知を提供します。

あなたはThread.Abort();メソッドを使用することができる第一の記事

0

でサンプルコードを参照してください、それは、スレッドを中止する最適な/最も安全な方法ではありません。

スレッドを終了する最も安全な方法は、適切なタイミングで終了するには、あなたの輸出クラスで余分なコードを追加することです。..

あなたは、スレッドが安全に終了する必要があることを私と一緒に同意のstackoverflowの答えのトンを見つけることができます

EDIT:Thread.Abort();を使用します。

+1

[いいえ、 'Thread.Abort()'](http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort)を使用しないでください。これは非常に悪いアドバイスです。 「あなたは常にThread.Abort()を使うことはできません。 –

+0

@MatthewWatson、あなたは答え全体を読んだ?あなたは答えをdownvotingのように感じた? – Yahfoufi

+0

はい、私は全体の答えを読んでいますが、最初の文章ではまだ 'あなたはいつもThread.Abort()を使うことができます。方法。その方法を決して使うべきではないことを明確にすべきであり、答えを始めるのはあなたが「いつも」それを使うことができるということではありません。なぜそれが悪い考えであるか分かりませんか?その文全体を削除するか、末尾に移動して「Thread.Abort()を使ってスレッドを中止しないでください」というようなものに変更してください。 –

関連する問題