Multithreading with C#
by Raffi Krikorian08/06/2001
So far we have talked about, compared, and contrasted C#'s and Java's syntax and input/output functionalities -- this time around we are going to talk about threading.
Threads are a powerful abstraction for allowing parallelized operations: graphical updates can happen while another thread is performing computations, two threads can handle two simultaneous network requests from a single process, and the list goes on. This article will focus on the syntactical differences between Java and C# threading capabilities as well as presenting a translation of a few common Java usage patterns into C#.
Conceptually, threads provide a way to execute code in parallel within the same program -- each thread executes instructions "simultaneously" (of course, on a single processor machine, this is accomplished by interweaving operations of the threads that are running) but within a shared memory space, so each thread can have access to same the data structures within a program. Because of this characteristic, the subtleties of multi-threaded operation come into play, as a program is likely to want to safely share data between the many different executing threads.
Creating and Running Threads
|
|
Java provides most of its threading functionality in the
java.lang.Thread and java.lang.Runnable classes. Creating a thread
is as simple as extending the Thread class and calling start(); a
Thread may also be defined by authoring a class that implements
Runnable and having that class passed into a Thread. Take the
following simple program -- we will have two threads both counting
from 1 to 5 simultaneously and printing it out
using System;
public class ThreadingExample
extends Object {
public static void main( String args[] ) {
Thread[] threads = new Thread[2];
for( int count=1;count<threads.length;count++ ) {
threads[count] = new Thread( new Runnable() {
public void run() {
count();
}
} );
threads[count].start();
}
}
public static void count() {
for( int count=1;count<=5;count++ )
System.out.print( count + " " );
}
}
We can translate this into C#, making use of the
System.Threading.Thread class and the System.Threading.ThreadStart
delegate:
using System.Threading;
public class ThreadingExample : Object {
public static void Main() {
Thread[] threads = new Thread[2];
for( int count=1;count<threads.Length;count++ ) {
threads[count] = new Thread( new ThreadStart( Count ) );
threads[count].Start();
}
}
public static void Count() {
for( int count=1;count<=5;count++ )
Console.Write( count + " " );
}
}
This example is a little deceiving, however. Where Java allows the
java.lang.Thread class to be extended and the java.lang.Runnable
interface to be implemented, C# does not provide these facilities.
A C# Thread is sealed and therefore it must be constructed with a
ThreadStart delegate that refers to a method that has both its
parameters and return value as void -- this simply means that
instead of using the inner class pattern (as above), an object will
need to be created and one of the object's methods must be passed to
the thread for execution.

