views:

124

answers:

1

I have 2 classes A and B, where they belongs to the same namespace but resides in seperate files namely a.cs and b.cs, where class B essentially is a helper wrapping a web service call as follow:

public class A
{
    public A() // constructor
    {
        protected static B b = new B();
    }

    private void processResult1(string result)
    {
        // come here when result is successful
    }

    private void processResult2(string result)
    {
        // come here when result is failed
    }
    static void main()
    {
        b.DoJobHelper(...);
    }
}

public class B
{
    private com.nowhere.somewebservice ws;
    public B()
    {
        this.ws = new com.nowhere.somewebservice();
        ws.JobCompleted += new JobCompletedEventHandler(OnCompleted);
    }
    void OnCompleted(object sender, JobCompletedEventArgs e)
    {
        string s = e.Result;
        Guid taskID = (Guid)e.UserState;
        switch (s)
        {
             case "Success":
             // Call processResult1(); 
             break;
             case "Failed":
             // Call processResult2(); 
             break;
             default: break;
        }
    }
    public void DoJobHelper()
    {
        Object userState = Guid.NewGuid();
        ws.DoJob(..., userState);
    }        
}

(1) I have seen texts on the net on using delegates for callbacks but failed to apply that to my case. All I want to do is to call the appropriate processResult() method upon OnCompleted() event, but dunno how to and where to declare the delegate:

public delegate void CallBack(string s);

(2) There is a sender object passed in to OnCompleted() but never used, did I miss anything there? Or how can I make good use of sender?

Any helps appreciated.

A: 

1)

public class A
{
    public A() // constructor
    {
        protected static B b = new B(processResult1, processResult2);
    }

    private void processResult1(string result)
    {
        // come here when result is successful
    }

    private void processResult2(string result)
    {
        // come here when result is failed
    }
    static void main()
    {
        b.DoJobHelper(...);
    }
}

public class B
{
    private com.nowhere.somewebservice ws;
    private Action<string> success;
    private Action<string> failure;
    public B(Action<string> success, Action<string> failure)
    {
        this.success = success;
        this.failure = failure;
        this.ws = new com.nowhere.somewebservice();
        ws.JobCompleted += new JobCompletedEventHandler(OnCompleted);
    }
    void OnCompleted(object sender, JobCompletedEventArgs e)
    {
        string s;
        Guid taskID = (Guid)e.UserState;
        //this switch will never do anything because s is null right now.
        //you'll need to check some actual state, or translate some other
        //state into the "Success" and "Failure" words for the s variable
        //before you call this switch statement.
        switch (s)
        {
             case "Success":
             {    
               success(s);
               break;
             }
             case "Failed":
             {
               failure(s);
               break;
             }
             default: break;
        }
    }
    public void DoJobHelper()
    {
        Object userState = Guid.NewGuid();
        ws.DoJob(..., userState);
    }        
}

2) don't bother using sender. it's only important if you have more than one object's events being handled by the same event handler method.

Derick Bailey
Thanks Derick.That'll work, but I want to try out the delegate in C#...hehe :-)
codemonkie
i don't understand the comment... this is valid C#... i write C# like this all day, every day
Derick Bailey
The above comment was me wondering if there is a way to apply the "delegate" construct to solve the programming problem, the only reason being to learn a new thing rather than anything else.I'm going to use your approach since it works and get the job done.Thanks and no offence, Derick.
codemonkie
System.Action<T> is a delegate. A delegate is basically an anonymous method pointer that allows you to pass a method call with the same signature as the delegate around like a variable, and call that method through the delegate. the code i wrote here is using delegates, exactly like you want. I just used a delegate that is built into the .net framework because there is no need to write your own.
Derick Bailey
if you REALLY want to write your own delegate, just add this line of code: public delegate void Action<T>(T value);
Derick Bailey
Pls accept my apologies for not knowing Action<T> is indeed a delegate, I realized that after reading up http://msdn.microsoft.com/en-us/library/018hxwa8.aspx.Thanks again, Derick.
codemonkie