Click here to Skip to main content
15,886,807 members
Articles / Programming Languages / C#
Article

Idiot's Guide to Grid Computing - Part I

Rate me:
Please Sign up or sign in to vote.
4.29/5 (10 votes)
4 Jun 2007CPOL3 min read 76.7K   1.4K   60   21
How to use grid computing with Alchemi.

Image 1

Introduction

Recently, I needed to do a lot of computing in a relatively short period of time, so I looked on Sourceforge.net for distributed computing. I found Alchemi, a .NET library used to implement grid computing.

Background

What is grid computing? Grid computing is the distribution of threads across a network or the Internet. A grid consists of a computer requesting threads to be executed (called the owner), a manager which sends the threads to computers who will execute them, and executors which execute the thread(s) assigned to them. Then, the results of the threads are sent back to the owner through the manager.

Using the Code

Alchemi makes grid computing quite easy to implement, using inherited classes and an application object.

The basic form of an application is like this:

C#
using System;
using Alchemi.Core;
using Alchemi.Core.Owner; 
namespace UselessApp 
{ 
    [Serializable] 
    public class MyThread : GThread 
    { 
        public override void Start() 
        { 
        } 
    } 
    class MultiplierApplication 
    { 
        static GApplication ga; [STAThread]
    
        static void Main(string[] args) 
        { 
            // create grid application 
            ga = new GApplication(new GConnection("localhost", 
                     9000, "user", "user")); 

            // tell the program to send itself over network 
            ga.Manifest.Add(new ModuleDependency(typeof(MyThread).Module)); 

            //create thread 
            MyThread thread = new MyThread(); 

            // add thread to application 
            ga.Threads.Add(thread);

            // start application 
            ga.Start(); 
        } 
    } 
} 

This would send the program over the network to an executor, then run the thread. The thread does nothing, so the program just shuts down. Before you run the code, you will need Alchemi. To get Alchemi, go here. You will need the manager and executor installers. After you install the manager and executor, you will need to reference the libraries, which are wherever you installed the manager and the executor (both locations). In order to run the useless application, you will need to start the manager and executor. Go to Start->Programs ->Alchemi, then into Manager or Executor, respectively. The default settings for the executor and manager will work. The basic application should compile and run now. Now, on to something more useful: GUID generation and comparing them to see if there are duplicates.

The Useful Application

Currently, you have the framework for an application that is completely useless. Let's expand on it by generating 300 GUIDs and comparing them (that was my Science project). First, let's add a constructor to the thread class. The class should look like this:

C#
[Serializable] 
public class MultiplierThread : GThread 
{ 
    private String current; 
    private String[] guids = new String[300]; 
    private int num=0; 
    private bool already = false; 
    int mystart, myend; 
    public int Result 
    { 
        get 
        { 
        return num; 
        } 
    } 
    public MultiplierThread(int start, int end, String[] guid) 
    { 
        mystart = start; 
        myend = end; 
        guids = guid; 
    } 
    ~MultiplierThread() 
    { 
        guids = null; 
    } 
    public override void Start() 
    { 
        for (int i = mystart; i < myend; i++) 
        { 
            current = guids[i]; 
            for (int n = 0; n < 300; n++) 
            { 
                if(current==guids[n]) 
                { 
                    if(already) num++; 
                    else already=true; 
                } 
                already=false; 
            } 
        } 
    } 
}

Next, we'll modify the application class to create the threads and add some variables. We will also add event handlers for the completion of the threads and the application. The class should look like this:

C#
class MultiplierApplication 
{ 
    static GApplication ga; 
    static int num; 

    [STAThread] 
    static void Main(string[] args) 
    {
         // create grid application 
        GConnectionDialog conndia = new GConnectionDialog(); 
        if (conndia.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
        { 
            ga = new GApplication(conndia.Connection); 
        } 
        else 
        { 
            Console.WriteLine("A connection must be created.");
            return; 
        } 
        // add GridThread module (this executable) as a dependency 
        ga.Manifest.Add(new ModuleDependency(typeof(MultiplierThread).Module)); 
        String[] guids = new String[300]; 
        for (int i = 0; i < 300; i++) 
        { 
            guids[i] = Guid.NewGuid().ToString(); 
        } 
        // create and add 300 threads to the application 
        for (int i = 0; i < 300; i++) 
        { 
            // create thread 
            MultiplierThread thread = new MultiplierThread(i, i+1, guids); 
            // add thread to application 
            ga.Threads.Add(thread); } 
            // subscribe to events 
            ga.ThreadFinish += new GThreadFinish(ThreadFinished); 
            ga.ThreadFailed += new GThreadFailed(ThreadFailed); 
            ga.ApplicationFinish += new GApplicationFinish(ApplicationFinished); 
            // start application 
            ga.Start(); 
        } 
    }

    static void ThreadFinished(GThread th) 
    { 
        // cast GThread back to MultiplierThread 
        MultiplierThread thread = (MultiplierThread) th; 
        Console.WriteLine( "thread # {0} finished with" + 
                " result '{1}'", thread.Id, thread.Result); 
        num = num + thread.Result; 
        GC.Collect(GC.GetGeneration(thread)); 
        GC.Collect(GC.GetGeneration(th)); 
    } 

    static void ThreadFailed(GThread th, Exception e) 
    { 
        Console.WriteLine( "thread # {0} finished with" + 
                           " error '{1}'", th.Id, e.Message); 
        GC.Collect(GC.GetGeneration(th)); 
    } 

    static void ApplicationFinished() 
    { 
        StreamWriter sw; 
        sw = new StreamWriter("results.txt"); 
        sw.WriteLine(); 
        sw.Write("Number of ambiguous GUIDs for " + 
                 "the Microsoft .Net algorithm: "); 
        Console.Write("Number of ambiguous GUIDs " + 
                      "for the Microsoft .Net algorithm: "); 
        sw.Write(num.ToString());
        sw.Close(); 
    } 
}

Don't forget the using statements (for I/O):

C#
using System; 
using Alchemi.Core; 
using Alchemi.Core.Owner;
using System.IO;

This will generate 300 GUIDs and compare them to each other. There is still room for improvement though, so let's add a connection dialog to the application. The connection dialog will allow the user to connect to a manager other than the owner. A connection dialog is supplied with the library, so we only need to change

C#
ga = new GApplication(new GConnection("localhost", 9000, "user", "user")); 

to

C#
// create grid application
GConnectionDialog conndia = new GConnectionDialog(); 
if (conndia.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
{ 
    ga = new GApplication(conndia.Connection);
} 
else 
{ 
    Console.WriteLine("A connection must be created."); 
    return; 
}

which will make a dialog pop up, requesting information for the connection.

Conclusion

Now that you know the basics of using Alchemi, you can do a lot more with multithreading. In my next installation of the Idiot's Guide to Grid Computing, I will show you how to use Alchemi with Managed C++.

Points of Interest

You can send all dependencies over the network using the manifest property of the Application class.

This application requires three dependencies (System, System.Windows.Forms, Alchemi.Core) and one source file.

History

  • Completed and uploaded tutorial at 7:01 PM on 11/24/06.
  • Updated on 06/04/07 at 1:31 PM.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Dealer Wizard, LLC.
United States United States
I'm a 19-year-old software developer living outside Charlotte, North Carolina in the United States. I started programming with QuickBasic when I was around 7 years old, and since then have devoted my life to it. Currently, I'm working at a small software company called Dealer Wizard, which provides, among other things, automated sales lead generation for car dealers.

Comments and Discussions

 
AnswerRe: How to use XPManager in Alchemi Pin
Julian Goldsmith18-Jun-07 13:56
Julian Goldsmith18-Jun-07 13:56 
QuestionProblem with C++/CLI [modified] Pin
shivack11-Apr-07 0:48
shivack11-Apr-07 0:48 
GeneralRe: Problem with C++/CLI Pin
Julian Goldsmith13-Apr-07 4:13
Julian Goldsmith13-Apr-07 4:13 
QuestionPerspective Please? Pin
Szegheo29-Nov-06 5:46
Szegheo29-Nov-06 5:46 
AnswerRe: Perspective Please? Pin
Julian Goldsmith29-Nov-06 10:34
Julian Goldsmith29-Nov-06 10:34 
GeneralRe: Perspective Please? Pin
Szegheo1-Dec-06 5:28
Szegheo1-Dec-06 5:28 
GeneralRe: Perspective Please? Pin
antecedents1-Dec-06 7:12
antecedents1-Dec-06 7:12 
GeneralRe: Perspective Please? Pin
Szegheo4-Dec-06 3:53
Szegheo4-Dec-06 3:53 
AnswerRe: Perspective Please? Pin
antecedents1-Dec-06 7:05
antecedents1-Dec-06 7:05 
AnswerRe: Perspective Please? Pin
Julian Goldsmith2-Dec-06 4:36
Julian Goldsmith2-Dec-06 4:36 
GeneralThnkz Pin
UnRusoDeCaracas24-Nov-06 16:54
UnRusoDeCaracas24-Nov-06 16:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.