Shamil Salakhetdinov
shamil at smsconsulting.spb.ru
Tue Jan 26 09:16:55 CST 2010
Hi John -- Here is a promised WinForms sample code with .InvokeRequired and .Invoke: using System; using System.Collections.Generic; using System.Windows.Forms; namespace WindowsFormsApp { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new TestForm()); } } // TestForm Designer partial class TestForm { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <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.cmdTest = new System.Windows.Forms.Button(); this.txtTest = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // cmdTest // this.cmdTest.Location = new System.Drawing.Point(128, 205); this.cmdTest.Name = "cmdTest"; this.cmdTest.Size = new System.Drawing.Size(75, 23); this.cmdTest.TabIndex = 0; this.cmdTest.Text = "&Test"; this.cmdTest.UseVisualStyleBackColor = true; this.cmdTest.Click += new System.EventHandler(this.cmdTest_Click); // // txtTest // this.txtTest.Location = new System.Drawing.Point(12, 13); this.txtTest.Multiline = true; this.txtTest.Name = "txtTest"; this.txtTest.Size = new System.Drawing.Size(311, 175); this.txtTest.TabIndex = 1; // // TestForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(335, 240); this.Controls.Add(this.txtTest); this.Controls.Add(this.cmdTest); this.Name = "TestForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Test Form"; this.Load += new System.EventHandler(this.TestForm_Load); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button cmdTest; private System.Windows.Forms.TextBox txtTest; } // TestForm Code Behind public partial class TestForm : Form { public TestForm() { InitializeComponent(); } private My.BusinessLayerClassLib.SpRunnerManager _runner; private void TestForm_Load(object sender, EventArgs e) { _runner = new My.BusinessLayerClassLib.SpRunnerManager(); _runner.StatusReport += new EventHandler<My.CoreClassLib.SpRunnerStatusReportEventArgs>(statusReport); } private void cmdTest_Click(object sender, EventArgs e) { txtTest.Text = null; _runner.Run(); } private void statusReport(object sender, My.CoreClassLib.SpRunnerStatusReportEventArgs e) { string message = string.Format("{0}: Processing {1} of {2}...", sender.GetType(), e.CurrentCount, e.MaxCount); if (txtTest.InvokeRequired) { object[] args = { message }; this.Invoke(new logDelegate(log), args); } else log(message); } private delegate void logDelegate(string message); private void log(string message) { txtTest.Text = message + System.Environment.NewLine + txtTest.Text; } } } // classlib1 namespace My.CoreClassLib { public class SpRunnerStatusReportEventArgs : EventArgs { public int CurrentCount { get; set; } public int MaxCount { get; set; } } } // classlib2 namespace My.UtilsClassLib { public class SpStatusReporter { public SpStatusReporter( EventHandler<My.CoreClassLib.SpRunnerStatusReportEventArgs> statusReport) { _statusReport = statusReport; } private EventHandler<My.CoreClassLib.SpRunnerStatusReportEventArgs> _statusReport; public void ReportStatus(int currentCount, int maxCount) { if (_statusReport != null) { My.CoreClassLib.SpRunnerStatusReportEventArgs e = new My.CoreClassLib.SpRunnerStatusReportEventArgs(); e.CurrentCount = currentCount; e.MaxCount = maxCount; _statusReport(this, e); } } } } // classlib3 namespace My.BusinessLayerClassLib { public class SpRunnerManager { public EventHandler<My.CoreClassLib.SpRunnerStatusReportEventArgs> StatusReport; private My.UtilsClassLib.SpStatusReporter _reporter; public void Run() { if (_reporter == null) _reporter = new My.UtilsClassLib.SpStatusReporter(StatusReport); const int MAX_COUNT = 5; for (int i = 1; i <= MAX_COUNT; i++) { _reporter.ReportStatus(i, MAX_COUNT); } } } }