|
-
Nov 10th, 2010, 11:50 AM
#1
Thread Starter
Not NoteMe
Event handlers
I'm using a class defined in an external library that allows access to a generic save device.
This class has an event handler for when it aquired the device.
I can then use the device to save/load, providing the device has been aquired.
I want to write an extension method that will perform a given method on the device if it's been aquired, and if it hasn't it will aquire it then perform the given method.
A first attempt as below:
Code:
public delegate void PostAquireDeviceAction();
public static void AquireDevicePerformAction(this SaveDevice saveDevice, PostAquireDeviceAction callMethod)
{
if (!saveDevice.HasValidStorageDevice)
{
saveDevice.PromptForDevice();
saveDevice.DeviceSelected += (sender, eventargs) =>
{
callMethod();
};
}
else
{
callMethod();
}
}
The issue with this is after calling this method, if the device is aquired again, that method will get called again (since it's a handler for the event).
How can i get round this issue?
Quotes:
"I am getting better then you guys.." NoteMe, on his leet english skills.
"And I am going to meat her again later on tonight." NoteMe
"I think you should change your name to QuoteMe" Shaggy Hiker, regarding NoteMe
"my sweet lord jesus. I've decided never to have breast implants" Tom Gibbons
Have I helped you? Please Rate my posts. 
-
Nov 10th, 2010, 05:57 PM
#2
Re: Event handlers
You could use a second method as the event handler instead. In that event handler, first detach itself as an event handler, then call the desired method.
-
Nov 10th, 2010, 06:03 PM
#3
Re: Event handlers
You can't unregister a lambda from an event handler, so you'll have to move that into a separate method, and then unregister the method as part of handling the event.
However, have you considered whether that is actually what you want to be doing? When your AquireDevicePerformAction method returns, there is no guarantee that the action has actually been performed... It would seem more logical for this method to block until the device has been acquired (if necessary) and then run the action. That way you can guarantee the action has been performed at the end of the method, which is the contract you're implying with the method name.
Does the API you're using have a blocking version of PromptForDevice? If not, you could use synchronisation primitives (such as a ManualResetEvent) to block until the DeviceSelected event fires.
-
Nov 11th, 2010, 03:34 AM
#4
Thread Starter
Not NoteMe
Re: Event handlers
Thanks for the replys.
Giraffe, I'm fine with it only calling the method if we have a valid device. If i find i need to then there are other events i can hook for if the device couldn't be aquired.
I can't block this thread because this is a game loop and the game loop needs to update in order to get the device (it shows a screen to the player). Possibly i should rename the method to bettwe reflect the intentions though.
I've taken in both your comments and have tried making the 'methodCaller' a method, as below:
Code:
public class MethodCallerEventArgs : EventArgs
{
public PostAquireDeviceAction CallMethod;
public SaveDevice SaveDevice;
public MethodCallerEventArgs(SaveDevice SaveDevice, PostAquireDeviceAction CallMethod)
: base()
{
this.SaveDevice = SaveDevice;
this.CallMethod = CallMethod;
}
}
public static void MethodCaller(object sender, MethodCallerEventArgs EventArgs)
{
EventArgs.SaveDevice.DeviceSelected -= MethodCaller;
EventArgs.CallMethod();
}
public static void AquireDevicePerformAction(this SaveDevice SaveDevice, PostAquireDeviceAction CallMethod)
{
if (!SaveDevice.HasValidStorageDevice)
{
SaveDevice.PromptForDevice();
SaveDevice.DeviceSelected += MethodCaller;
}
else
{
CallMethod();
}
}
The issue i get now though, is that i've had to create a new eventargs class so i can pass in my method to call and because of that the method can't be used as an event handler for the DeviceSelected event.
Last edited by SLH; Nov 11th, 2010 at 03:38 AM.
Quotes:
"I am getting better then you guys.." NoteMe, on his leet english skills.
"And I am going to meat her again later on tonight." NoteMe
"I think you should change your name to QuoteMe" Shaggy Hiker, regarding NoteMe
"my sweet lord jesus. I've decided never to have breast implants" Tom Gibbons
Have I helped you? Please Rate my posts. 
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|