代码之家  ›  专栏  ›  技术社区  ›  AngryHacker

在WinForms应用程序中杀死后台任务的公认模式是什么

  •  2
  • AngryHacker  · 技术社区  · 15 年前

    当用户点击离开时,我想处理UserControl和它所拥有的所有资源(包括后台线程)。这样做的最佳方式是什么?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Eric J.    15 年前

    在BackgroundWorker上调用CancelAsync方法并等待其终止。构造工作代码,以便它经常检查cancel标志。

    编辑:演示代码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class FrmMain : Form
        {
            public FrmMain()
            {
                InitializeComponent();
            }
    
            private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                MessageBox.Show("BG Done");
            }
    
            private void btnStart_Click(object sender, EventArgs e)
            {
                bg.WorkerSupportsCancellation = true;
                bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
                bg.DoWork += new DoWorkEventHandler(bg_DoWork);
                bg.RunWorkerAsync();
            }
    
            void bg_DoWork(object sender, DoWorkEventArgs e)
            {
                int i=0;
    
                while (!bg.CancellationPending)
                {
                    lblStatus.BeginInvoke((MethodInvoker) delegate { lblStatus.Text = i + " sec."; });
                    System.Threading.Thread.Sleep(1000);
                    i++;
                }
    
                lblStatus.BeginInvoke((MethodInvoker)delegate { lblStatus.Text = "CANCEL"; });
            }
    
            private void btnStop_Click(object sender, EventArgs e)
            {
                bg.CancelAsync();
                while (bg.IsBusy) // For real code limit max wait time in while loop
                {
                    System.Threading.Thread.Sleep(50);
                    Application.DoEvents();
                }
                this.Close();
            }
        }
    }
    
    
    namespace WindowsFormsApplication1
    {
        partial class FrmMain
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components;
    
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.bg = new System.ComponentModel.BackgroundWorker();
                this.btnStart = new System.Windows.Forms.Button();
                this.btnStop = new System.Windows.Forms.Button();
                this.lblStatus = new System.Windows.Forms.Label();
                this.SuspendLayout();
                // 
                // bg
                // 
                this.bg.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.bg_RunWorkerCompleted);
                // 
                // btnStart
                // 
                this.btnStart.Location = new System.Drawing.Point(39, 13);
                this.btnStart.Name = "btnStart";
                this.btnStart.Size = new System.Drawing.Size(75, 23);
                this.btnStart.TabIndex = 0;
                this.btnStart.Text = "Start";
                this.btnStart.UseVisualStyleBackColor = true;
                this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
                // 
                // btnStop
                // 
                this.btnStop.Location = new System.Drawing.Point(39, 42);
                this.btnStop.Name = "btnStop";
                this.btnStop.Size = new System.Drawing.Size(75, 23);
                this.btnStop.TabIndex = 1;
                this.btnStop.Text = "Stop";
                this.btnStop.UseVisualStyleBackColor = true;
                this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
                // 
                // lblStatus
                // 
                this.lblStatus.AutoSize = true;
                this.lblStatus.Location = new System.Drawing.Point(39, 72);
                this.lblStatus.Name = "lblStatus";
                this.lblStatus.Size = new System.Drawing.Size(73, 13);
                this.lblStatus.TabIndex = 2;
                this.lblStatus.Text = "(Not Running)";
                // 
                // FrmMain
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(423, 136);
                this.Controls.Add(this.lblStatus);
                this.Controls.Add(this.btnStop);
                this.Controls.Add(this.btnStart);
                this.Name = "FrmMain";
                this.Text = "Main";
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
    
            #endregion
    
            private System.ComponentModel.BackgroundWorker bg;
            private System.Windows.Forms.Button btnStart;
            private System.Windows.Forms.Button btnStop;
            private System.Windows.Forms.Label lblStatus;
        }
    }
    
        2
  •  1
  •   ChaosPandion    15 年前

    你可能想钓到鱼 Progress Changed Event . 让您的工作人员在不丢失工作的情况下安全停止该事件时调用该事件。现在,您可以通过在中设置值来存储任务的当前状态 ProgressChangedEventArgs 然后你就可以在不损失工作的情况下重新开始工作了。