关闭表单时停止在线程中运行方法

时间:2016-11-04 08:48:34

标签: c# multithreading forms winforms

我的代码有问题。我正在创建一个具有主窗体的图形应用程序。当我点击一个按钮时,我创建了一个新的表单,在导出一些文件时显示一个进度条。当我尝试使用进度条关闭表单时,我的问题就开始了,因为导出文件的方法不会结束。

在新表单中,我执行一个检查导出进度并填充进度条的方法,此方法每秒执行一次。要导出我创建一个新线程,该线程执行导出方法。

如果导出完成,表单和线程正确关闭,但如果我通过关闭表单“强制”停止操作,则导出的线程不会停止,直到导出结束或关闭主窗体。

那么,我怎么能阻止那个线程?

这是我的代码:

 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();

        }
    }

3 个答案:

答案 0 :(得分:0)

这里要理解的是:运行“导出到文件”(Exporter.ExportToFile)...的代码可能写入要停止。

换句话说:您想要增强该组件。如果你真的想在这样的环境中使用它,那么你肯定想要向导出器添加另一种方法;例如“AbortExport”或类似的东西!

(而不是仅仅杀死底层线程 - 例如,您可能希望确保删除该导出创建的任何文件;并且所有关联的资源都会看到正确的清理)

答案 1 :(得分:0)

为什么不使用任务呢?

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

  

通过抛出OperationCanceledException并向其传递请求取消的令牌。执行此操作的首选方法是使用ThrowIfCancellationRequested方法。以这种方式取消的任务将转换为Canceled状态,调用代码可以使用该状态验证任务是否响应了其取消请求。

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

  

实施合作取消模型的一般模式是:

     
      
  • 实例化一个CancellationTokenSource对象,该对象管理并向各个取消令牌发送取消通知。

  •   
  • 将CancellationTokenSource.Token属性返回的标记传递给侦听取消的每个任务或线程。

  •   
  • 为每个任务或线程提供响应取消的机制。

  •   
  • 调用CancellationTokenSource.Cancel方法以提供取消通知。

  •   

请参阅第1篇文章中的示例代码

答案 2 :(得分:0)

您可以使用<?php add_filter( 'excerpt_length', 'custom_excerpt_length', 999 ); function custom_excerpt_length( $length ) { return 25; } ?> 方法,但不是最佳/最安全方式中止线程。

退出线程最安全的方法是在导出器类中添加额外的代码以便在正确的时间退出..

你可以在stackoverflow上找到大量的答案,我同意我应该用户代码安全地退出线程。

编辑:使用Thread.Abort();是一个坏主意,我认为原来的答案很清楚