0

I have created a class that handles encrypted database traffic. I have used external Event definitions successfully, allowing the calling process to properly handle errors that - while they occurred within the database module - actually originated from the calling procedure.

Using the external Error handler I would do the following:

public event EventHandler ErrorStatusChanged;

...and later, if/when such occurred, I would handle it like this:

if (ErrorStatusChanged != null)
   {
      ErrorStatusChanged(this, EventArgs.Empty);
   }

...and that seems to work just fine. However, now I want to extend further using a callback function, but I have only a few clues how I might approach this situation. (I feel sure that it is possible to accomplish this, but I'm fairly lost/confused as to actual implementation...)

Something like:

public delegate void Update_System_Status (bool dbConnected, string textStatus);

...and then later (I'm sure I've got this wrong, the compiler flags it even before compile time):

if (Update_System_Status != null)
   {
       Update_System_Status(bConnFlag, sConnTextStatus);
   }

I'd like to build a couple of callbacks - one that allows the datahandler class to inform the calling process that it has successfully connected (or not), and another to handle updating a progress bar during the longer mass-update processes. And after numerous searches using [callback] and/or [delegate] as keywords, I'm getting nowhere quickly. I am, however, getting really confused!

I had envisioned that I would provide some sort of interface, very similar to the EventHander (above) and be able to determine - later on, when it is needed - whether the calling procedure provided the proper function, and call it if/when possible. I know that not all programmers will want to provide a main form update callback function to this database handler, so I figure I'll need to somehow "know" when one has been provided, and when not.

I have unsuccessfully employed the [delegate] keyword, and have no idea how to use the [interface] directive at all - all of the examples I keep running into illustrate the functions being internal to the class, which is exactly not what I am trying to achieve. I am trying to provide a framework that will allow an external process to provide a function that, when something happens inside the class/object that would be good to update the external (calling) system, could do so by calling the provided function (from outside).

Thanks (in advance) for your assistance - I'm lost!

LongFist
  • 3
  • 1

2 Answers2

0

I think you problem is that you are only declaring a delegate type - you are not declaring a property of that type

Try something like this:

public delegate void MyDelegateType(bool dbConnected, string textStatus);
public MyDelegateType Update_System_Status { get; set; }

then you should be able to use it like you want:

if (Update_System_Status != null)
{
    Update_System_Status(bConnFlag, sConnTextStatus);
}

but if you are going to use it like this you might aswell make it an event:

public event MyDelegateType MyEvent;
JoaoFSA
  • 267
  • 1
  • 7
  • I wasn't sure how to make it an event and still pass those values back to the external function - which is why I decided to use Delegates. You have, I think, provided me with the rosetta stone I so desperately need in order to begin to understand how to make this work. I'm going to try this immediately (since it looks as if the only step I missed was the second [public MyDelegateType Update_System_Status { get; set; }] instantiation in the code --- I think you may have unlocked the mystery here. Let me try this... – LongFist Sep 17 '15 at 15:26
  • Sir, I am in awe. You have revealed to me that which I couldn't glean from other examples: it works exactly as I had hoped. You are right - I hadn't actually instantiated it yet, so I was almost there. This is WONDERFUL!!! Thank you again!!! – LongFist Sep 17 '15 at 15:33
  • Events are not really callbacks, they are multicast delegates (means multiple subscribers), moreover callbacks can return value, while it's [awkward](http://stackoverflow.com/q/1210026/1997232) idea for events. – Sinatr Sep 18 '15 at 07:05
0

You declared delegate correctly. What you are missing is a member of this class what will use that delegate declaration. The code you tries is valid for events (which are multicast delagates), though you omit event definition itself (therefore you code doesn't work). Callbacks are usually passed via method calls (but you can as well pass it via property):

public void DoSomething(Update_System_Status callback)
{
    // call callback
    callback?.Invoke(false, "some status");
}

or

public Update_System_Status Callback {get; set;}

// and then somewhere (using pre C# 6.0 syntax)
var callback = Callback;
if(callback != null)   
    callback(true, "some status");

If you don't need proper parameter names (in your case they have different type, so impossible to make mistake which is which), then you can simply use Action<> without need to declare delegate before:

public void DoSomething(Action<bool, string> callback) { ... }
Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • Here's where I get confused: wouldn't this approach *require* that a calling process provide the callback function? And would it be possible that the programmer using my object not get the callback function's arguments right? The idea was to make the callback (sort of) optional, in case the other programmer was kit-bashing something together and didn't have time (or capacity) to make it flashy. - or am I waaaayyyy over-complicating this? – LongFist Sep 17 '15 at 15:23
  • Method parameters can be optional or you can override method (to have version without callback). For callbacks what return value use `Func<>`. I don't really understand the problems you are afraid of. User of your class (another programmer) will see it is using callback from method definition. You should try to give him the most of help by naming things properly and commenting. Without concrete example you are indeed over-complicating simple things. See e.g. [this](http://stackoverflow.com/a/32481288/1997232) for an example (`canExecute` is optional callback). – Sinatr Sep 18 '15 at 07:00