views:

289

answers:

3

I'm looking to implement a synchronous and asynchronous version of a method within a class library. Currently I've done this so that the Async method fires off a new Thread and does it's processing. To determine if the action has completed the user should poll a property to see if it has finished.

I'd like to improve it, I think it would be better to use some form of Async callback or result, but I'm not really sure how to go about implementing it, or, if indeed it is necessary. Can anyone offer any advice?

+5  A: 
public static void Queue(Action action, Action done) {
    ThreadPool.QueueUserWorkItem(_ =>
    {
        try {
            action();
        } 
        catch (ThreadAbortException) { /* dont report on this */ } 
        catch (Exception ex) {
            Debug.Assert(false, "Async thread crashed! This must be fixed. " + ex.ToString());
        }
        // note: this will not be called if the thread is aborted
        if (done != null) done();
    });
}

Usage:

    Queue( () => { Console.WriteLine("doing work"); }, 
           () => { Console.WriteLine("work was done!"); } );
Sam Saffron
Beautiful method. +1.
Mehrdad Afshari
A: 

Asynchronous Delegates could be another option.

Read about Asynchronous Programming Using Delegates on MSDN

AB Kolan
+2  A: 

You can use a callback method instead of polling. Check out my answer on AsyncCallback

Edited:

Example of FileCopy using own async delegates with callback:

    public class AsyncFileCopier
    {
        public delegate void FileCopyDelegate(string sourceFile, string destFile);

        public static void AsynFileCopy(string sourceFile, string destFile)
        {
            FileCopyDelegate del = new FileCopyDelegate(FileCopy);
            IAsyncResult result = del.BeginInvoke(sourceFile, destFile, CallBackAfterFileCopied, null);
        }

        public static void FileCopy(string sourceFile, string destFile)
        { 
            // Code to copy the file
        }

        public static void CallBackAfterFileCopied(IAsyncResult result)
        {
            // Code to be run after file copy is done
        }
    }

You can call it as:

AsyncFileCopier.AsynFileCopy("abc.txt", "xyz.txt");
Rashmi Pandit
Indeed, however on further reading you're just using the FileStream.BeginRead() method which triggers the call back. I need to write my own callback, though I suppose thinking about it it may just be a case of passing in a delegate to use for triggering an event later on...
Ian
You can use asynchronous delegates and do a BeginInvoke to specify your own callback.
Rashmi Pandit