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

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

Mandarin Vocabulator

Posted on May 30th, 2005 in C#, Chinese by Patrick

Intro
This is a simple C# program I wrote in 2004 to help me study Chinese.

How It Works

  • You tell the Vocabulator which characters you want to practice (by selecting Week Numbers and Core/Supplementary categories)
  • You scroll through the (optionally randomised) list.
  • You can choose to display Characters by themselves (without the Pinyin) to test your character recognition, or alternatively view only Pinyin to practice your writing skills. (In the future I might integrate the WinXP writing pad so that you can test your characters properly — including stroke order!).
  • You can also test yourself against the clock and view your self-defined list as a slideshow.
  • I’m also thinking of adding a nice interface for adding/categorising your own characters (at the moment they’re hardwired into the source code) so that you can use the Vocabulator to revise just the ‘hard’ characters etc..

Download
Save this file to your desktop

Installation
You need to have the standard Chinese Font “simsun.ttc” installed. If you’re using Windows XP, you do this by installing “Files for East Asian Languages” in “Regional and Language Options” (through the Control Panel). For other windows varients you may have to download and install the font manually. This program is written in C# so you also need to have the latest .NET framework installed (from Micro$oft Windows Update).

Character List
The following Excel Spreadsheet contains all the Chinese Characters currently included in the program: WordList.xls. These thousand-odd Chinese words make up the entire content of Melbourne Univeristy’s First Year (Introductory) Chinese Course. The list was created by Du Liping of the Melbourne Institute of Asian Languages and Societies. Thanks Du Laoshi!