AsyncCallback called twice on Exception

C

Craig Vermeer

Hi All,

I noticed an interesting issue the other day, and thought someone here
might be able to shed some light on things.

I have a situation where I'm using asynchronous delegates, and an
exception is getting thrown from within the AsyncCallback on the
delegate. For some reason, this causes the AsyncCallback delegate to be
executed twice. Now, I understand how to stop the situation from
happening. However, what I didn't know was why things behaved the way
they did.

Below is a 'short but complete' code sample that demonstrates the behavior.

Thanks,
Craig



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace AyncDelegateIssueDemo
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private delegate void TestHandler(string message);
private event TestHandler CallbackEvent;
private event EventHandler AsyncEvent;

public Form1()
{
InitializeComponent();
AsyncEvent += new EventHandler(Form1_AsyncEvent);
AsyncEvent.BeginInvoke(this, EventArgs.Empty, new
AsyncCallback(OnAsyncCompleted), AsyncEvent);
CallbackEvent += new TestHandler(Form1_CallbackEvent);
}

private void OnAsyncCompleted(IAsyncResult res)
{
string message = "done";
try
{
((EventHandler)res.AsyncState).EndInvoke(res);
}
catch(Exception ex){message = ex.Message;}
Invoke(CallbackEvent, new object[]{message});
throw new Exception("test");
}

#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.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBox1.Location = new System.Drawing.Point(0, 0);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(292, 273);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void Form1_AsyncEvent(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(1000);
}

private void Form1_CallbackEvent(string message)
{
this.textBox1.Text += (message + Environment.NewLine);
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top