Asynchronous Programming in C#

Posted on June 4th, 2006 in C# by Patrick

Quite often when writing GUI apps, (especially ones that do things over the network), it is desirable to call a synchronous method asynchronously. When you create a delegate in C#, the compiler generated delegate derived class contains a BeginInvoke and EndInvoke functions that let you do this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Runtime.Remoting.Messaging;

namespace NetAsyn
{
public partial class Form1 : Form
{
private delegate string LongOperationDelegate(string longOpInput);
private delegate void LongOperationProcessOutputDelegate(string longOpOutput);

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
AsynchronousExample();
}
private void SynchronousExample()
{
WebClient wc = new WebClient();
tb_Output.Text = wc.DownloadString(tb_Input.Text);
}
private void AsynchronousExample()
{
// Create the object that we want to pass to LongOperation
string longOpInput = tb_Input.Text;

// Create delegate for method that will do the work
LongOperationDelegate MyDelegate = new LongOperationDelegate(LongOperation);

// Create callback for method that will run when work is finished
AsyncCallback longOpCallback = new AsyncCallback(LongOperationCallback);

// Start work with delegate's BeginInvoke method (LongOperation's arguements come first, then callback and state object
// NB: State object can be anything you want to pass to the callback
IAsyncResult result = MyDelegate.BeginInvoke(longOpInput, longOpCallback, null);

// We could use result to call EndInvoke here (would block until work finished) or to repeatedly poll work thread
// Since we're using callback instead, result isn't used
}
private string LongOperation(string longOpInput)
{
WebClient wc = new WebClient();
return wc.DownloadString(longOpInput);
}
private void LongOperationCallback(IAsyncResult result)
{
// This method is called by LongOperation just before the thread returns, which means it is called on a separate thread to the GUI

// Get a reference to the delegate (alternatively make the delegate global or pass it as the state object - last object of BeginInvoke)
LongOperationDelegate longOperationDelegate = (LongOperationDelegate)((AsyncResult)result).AsyncDelegate;

// Get the result of the work by calling EndInvoke
string longOpOutput = longOperationDelegate.EndInvoke(result);

// Because this method is called on a separate thread to the GUI, we have to use InvokeRequired tests to access GUI objects
LongOperationProcessOutput(longOpOutput);
}

private void LongOperationProcessOutput(string longOpOutput)
{
// Because this method is called on a separate thread to the GUI, we have to use InvokeRequired to access GUI objects
if (this.InvokeRequired)
{
// Create a delegate for this method, to execute back on the GUI thread
LongOperationProcessOutputDelegate processLongOpDelegate = new LongOperationProcessOutputDelegate(LongOperationProcessOutput);

// Invoke the delegate, passing in the output from the work thread
this.Invoke(processLongOpDelegate, longOpOutput);
}
else
{
// Do the actual processing (we are now in the GUI thread)
tb_Output.Text = longOpOutput;
}
}
}
}

  • Comments Off

Port Tester in C#

Posted on June 1st, 2006 in C# by Patrick

I deal with firewalls and web services a lot at work, and a lot of times when things break (or when deploying a new service) the easiest way to diagnose problems is to fire up telnet and try connecting to the port that the web service is supposed to be listening on. If you're in charge of the firewall it's also nice to be able to quickly eliminate the firewall as the prime suspect for a failure, eg. look the port is open, the firewall isn't blocking things!

For fun, I decided to write an app that would let me do quick port testing from a GUI. I wrote it in C# (.NET 2) since I've been doing lot of C# development lately.

This is what my PortTester looks like:
Screenshot

You can download the installer here (will ask you to download .NET 2 if you don't already have it installed).

Some features / implementation notes:

  • Remembers your last Host/Port using .NET DataBinding and ApplicationSettings (a really simple (~2sec) way of making your app remember user preferences)
  • IAsyncResult and a callback delegate to make Net.Socket operations Asynchronous (so that the app doesn't lock up while a connection times out)
  • The original goal of the app was just to check if a port was open, but once I'd started it seemed like a good idea to be able to send simple strings to the port so that you can interact with a service. For example, it's really handy to be able to connect to port 25 on a host and try sending mail:
    1. HELO somename
    2. MAIL FROM: me@address.com
    3. RCPT TO: dest@address.com
    4. DATA
    5. ….

    If you're having trouble with relaying being blocked etc.. the above method will usually trigger a helpful message from the mail server as to why your message is getting blocked. Of course I didn't want to write a complete telnet client, so I'm trying to resist the temptation to add extra features.. ;)

  • A certain amount of intelligence as to how to respond to the Enter key being pressed. For example, if you haven't connected yet the Enter key will trigger the Connect button. If you are connected, hitting Enter whilst in the Send textbox will send that text to the server, whereas if you're in the Host/IP textboxes hitting Enter will drop the current connection and connect to the new Host/IP. That combined with automatic positioning of the cursor depending on Connection state means that most of the time you don't need to use the mouse at all.
  • Phone icon from IconBuffet, one of my fav sources of free stock icons for software projects
  • Comments Off