[dba-VB] C#: Raising events

Shamil Salakhetdinov shamil at smsconsulting.spb.ru
Mon Jan 25 11:34:09 CST 2010


Hi John --

Here is one of myriads possible solutions how to handle events in caller
classes - for form's(/their controls') code behind it will be similar with
an exception that you might have to use .Invoke while processing events in
event sinks as the latter could run in a different thread than your form's
main thread:

using System;

namespace ConsoleApplication
{

    public class SpRunner
    {
        public class  SpRunnerStatusReportEventArgs:EventArgs 
        {
            public int CurrentCount {get; set;}
            public int MaxCount {get;set; }
        }

        public EventHandler<SpRunnerStatusReportEventArgs> StatusReport;  
        public void Run()
        {
            const int MAX_COUNT = 5;
            for (int i = 1; i <= MAX_COUNT; i++)
            {
                if (StatusReport != null)
                {
                    SpRunnerStatusReportEventArgs e = new
SpRunnerStatusReportEventArgs();
                    e.CurrentCount = i;
                    e.MaxCount = MAX_COUNT;
                    StatusReport(this, e); 
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            SpRunner runner = new SpRunner();
            runner.StatusReport +=
                new
EventHandler<SpRunner.SpRunnerStatusReportEventArgs>(statusReport);
            runner.Run(); 
        }

        private static void statusReport(object sender,
SpRunner.SpRunnerStatusReportEventArgs e)
        {
            System.Console.WriteLine("{0}: Processing {1} of {2}...",
               sender.GetType(), e.CurrentCount, e.MaxCount);  
        }
    }
}

Thank you.

--
Shamil

-----Original Message-----
From: dba-vb-bounces at databaseadvisors.com
[mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: Monday, January 25, 2010 7:50 PM
To: VBA
Subject: [dba-VB] C#: Raising events

Silly me, I thought that events would be easy in C#.  I guess once you
figure them out they probably
are, but coming from VBA where all the behind the scenes stuff is done for
you, it is kinda confusing.

What I want to do is execute stored procedures, and publish status
information about each SP
executed on my form starts a process running.

I have a class which encapsulates my stored procedure stuff for creating the
command object,
capturing the parameters and eventually executing the stored procedure.

I assume that this object might raise an event when the stored procedure
returns i.e.
sCmd.ExecuteNonQuery() returns control to C# ?

OTOH, I have other classes which USE the SP class.  These are the classes
that actually call
specific stored procedures, pass parameters, and control the program flow
depending on whether the
called SP succeeds or fails etc.  THESE classes should raise an event, sunk
on the form, which
passes up the SP class instance just executed, IOW I just executed a "Create
index" stored procedure
and want to display on the form the name of the sp and whether it completed
satisfactorily, how long
it took and so forth.

I am going to go with the classes which execute sequences of SPs being the
class that raises the
event.  I am looking at this as an example:

http://www.codeproject.com/KB/cs/csevents01.aspx

clsStoredProc creates the command object, packages the parameters, and
executes the stored procedure.

clsAZExport uses a sequence of stored procedures to perform an export
process.

So... I create an event delegate definition which defines the event I will
raise.  Where do I place
this?  For the moment I have placed it inside of the container where
clsStoredProc is defined.

I now have to create evargStoredProcedure - a public class for the argument
that this event will
pass up to the form.  The argument is going to be the current instance of
the clsStoredProc.  Where
is this class created?  Do I just define a new class at the project level
for this event argument.
It seems that it is part and parcel of using clsStoredProcedure (which is in
its own project) so
placing it in the code container for that class seems appropriate.  For the
moment I have placed it
inside of the container where clsStoredProc is defined.


Now, in every method of clsAZExport I add two lines:

	evargStoredProcedure svargSP = new evargStoredProcedure(sp);
	evStoredProc(this, svargSP);

This apparently creates the arguments object and then raises the event.

Man oh man, is this a PITA (after VBA).  I haven't even begun to sink the
event yet.

So... back in the form which uses clsAZExport to export data from SQL
Server...

At this point their example breaks down entirely.  I am not writing to the
debug window, I am trying 
to write to a control on a form.  While the debug window can be written to
from anywhere, a control 
on a specific form is decidedly specific.  Thus the form has to somehow sink
the evStoredProc.

And I grind to a halt, unable to figure out what to do next.  It seems that
my clsAZExport declared 
in the form has an event evStoredProc, and that I need to wire that.  I kind
of figured that once I 
did all this I would click on any object that raises an event and I would
see a list of their 
events, but I do not, or I do not know how to see them.  As an example if I
have a text box, it has 
events.  If I click on that I can see its events, select one and voila, a
place to say what to do. 
How do I do that for an event raised by my class dimensioned and used in my
form?

If anyone is following this and knows what I am trying to do and what to do
next, please speak up.

-- 
John W. Colby
www.ColbyConsulting.com






More information about the dba-VB mailing list