/ / Aký je akceptovaný vzor zabíjania úloh na pozadí v aplikácii WinForms - .net, winforms, backgroundworker, dispose

Aký je akceptovaný vzor usmrcovania úloh na pozadí v aplikácii WinForms - .net, winforms, backgroundworker, dispose

Mám aplikáciu .net WinForms. Mám UserControl, ktorý je okamžite vytvorený na základe akcie používateľa - po okamžitom vykonaní vykonáva niektoré časovo náročné úlohy na pozadí vlákna (pomocou BackgroundWorker), pričom zobrazuje ajaxovú rotačnú animáciu. Užívateľ môže kedykoľvek kliknúť preč a potom kliknúť späť na ovládanie používateľa (čím by sa znova spustilo vlákno na pozadí).

Keď používateľ klikne, chcem sa zbaviť UserControl a všetkých zdrojov, ktoré má v držbe (vrátane vlákna na pozadí). Aký je najlepší spôsob, ako to dosiahnuť?

odpovede:

1 pre odpoveď č. 1

Zavolajte metódu CancelAsync na BackgroundWorker a počkajte, kým sa ukončí. Zostavte si kód pracovníka, aby často kontroloval príznak zrušenia.

Ak neexistujú žiadne negatívne vedľajšie účinky, akvlákno bude chvíľu bežať a nebude žiadnym spôsobom odkazovať na kontrolu užívateľa alebo akýkoľvek prostriedok, ktorý má v držbe, môžete sa zbaviť kontroly užívateľa po požiadaní o ukončenie vlákna.

EDIT: Demo kód

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;
}
}

1 pre odpoveď č. 2

Možno budete chcieť pripojiť k internetu Udalosť bola zmenená, Nechajte svojho pracovníka vyvolať túto udalosť vždy, keď sa dá bezpečne zastaviť bez straty práce. Teraz s týmto môžete uložiť aktuálny stav úlohy nastavením hodnoty v ProgressChangedEventArgs a potom môžete reštartovať, kde ste prestali, bez straty práce.