Click to See Complete Forum and Search --> : Defining CallBack methods


rliq
January 20th, 2010, 09:40 PM
I have a Cache class, one of it's methods is:


public Byte[] GetFile(String fileName)
{
...
}


Behind the scenes it gets the file from the Cache, else the Web. It works fine. Obviously, when it has to get it from the Web, it takes longer. Therefore I want my Cache class to also provide the following method.


public void GetFileAsync(String fileName, /* some callback function that allows me to return the Byte[] */)


In this method I create a BackgroundWorker and start it.
In the DoWork(), I call my normal GetFile(...). I understand I will have to lock{} stuff etc...
In the RunWorkerCompleted I assume I need to call the user of my Cache class's callback passing the file data.

I just can't get the syntax right. How/where do I define the callback, so the user of my Cache class knows it's signature and how to get the Byte[] data?

Here's my test code snippit, with some bits commented:

private class InputParameters
{
public /* ???? */ CallBack;
public String FileName;
}

private class OutputParameters
{
public /* ???? */ CallBack;
public Byte[] FileData;
}

public void GetFileAsync(/* ???? */ callBack, String fileName)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

InputParameters parameters = new InputParameters();
parameters.CallBack = callBack;
parameters.FileName = fileName;

worker.RunWorkerAsync(parameters);
}

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
InputParameters inputParameters = e.Argument as InputParameters;

OutputParameters outputParameters = new OutputParameters();
outputParameters.CallBack = inputParameters.CallBack;
outputParameters.FileData = GetFile(inputParameters.FileName);

e.Result = outputParameters;
}

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
OutputParameters parameters = e.Result as OutputParameters;

parameters.CallBack(parameters.FileData); // ????
}


Or am I barking up the wrong tree alltogether?

rliq
January 20th, 2010, 11:07 PM
ok... I've improved on that code and created a delegate:

public delegate void FileGetCallBack(Byte[] fileData);

And I now have it working.... But any alternatives/advice would be appreciated.

mariocatch
January 21st, 2010, 10:46 AM
You should use events.

Basically the concept is:
- Client registers to event GetFileCompleted
- Client calls GetFileAsync(...)
- When GetFileAsync completes, it should fire the event GetFileCompleted
- Client will be notified through the .Net event system, and all is well.

rliq
January 21st, 2010, 06:56 PM
I did consider that. But decided to go with the Callback. I'm not too sure the reasons/benefits for choosing one over the other...

BigEd781
January 21st, 2010, 07:00 PM
You are basically reinventing the built in event system with your callback parameter. The functional difference is that you are not allowing for multicast callbacks, i.e., only the caller of the functiopn may be notified of the "event". A C# event IS a multicast callback mechanism.

rliq
January 21st, 2010, 08:12 PM
That is the initial reason I did not consider creating an Event, as I do not need it to be a multicast callback. I've refactored my code dramatically since the earlier post.

BigEd781
January 21st, 2010, 08:47 PM
That is the initial reason I did not consider creating an Event, as I do not need it to be a multicast callback. I've refactored my code dramatically since the earlier post.

But why limit yourself? C# has a built in mechanism for callback operations. You will miss out on any improvements and/or bug fixes that are applied to it. I don't get it.

mariocatch
January 22nd, 2010, 10:47 AM
And I now have it working.... But any alternatives/advice would be appreciated.

We're giving you the .NET standard for what you're trying to achieve :) Events are definitely the way to go for what you are doing.