Reputation: 816
I have multiple chunks of code similar to the following:
void GetPerson(Action<PersonView, Exception> callback);
...
IsBusy = true;
_personRequested = true;
_service.GetPerson((person, error) =>
{
if (error != null)
{
return;
}
_person = person;
_personLoaded = true;
IsBusy = false;
});
The problem I am running in to is that a given class might fire off multiple different async calls, and the IsBusy property has to be 'smart' to not toggle off just because call 'A' is completed, but 'B' and 'C' are still pending. Hence the _personRequested and _personLoaded booleans. However, I'd like to go to something more generic, but am a bit unsure how to proceed.
My initial thought was to set up a function that takes in the above code as a delegate, but I keep getting bogged down by odd syntax. I'd like functionality such that I'd simply wrap the whole thing and pass it to my function as an anonymous method, then in that function and the callback I'd handle my classes' busy states.
Any help is appreciated, thanks.
Upvotes: 2
Views: 426
Reputation: 7110
I would probably consider to wrap the booleans and the logic about them into a "state machine" or something similar: http://www.codeproject.com/KB/architecture/statepatterncsharp.aspx
Upvotes: 1
Reputation: 10598
use a counter and increment for each start and decrement at end, make sure you make it race safe
Upvotes: 0
Reputation: 185593
If all you're looking for is an indicator that something's in use, you're probably better off using a counter rather than a simple boolean flag. You can then use Interlocked.Increment
and Interlocked.Decrement
to modify the value in a thread-safe way.
Declare this at the class level:
private volatile int isBusyCounter;
Interlocked.Increment(ref isBusyCounter);
_personRequested = true;
_service.GetPerson((person, error) =>
{
if (error != null)
{
return;
}
_person = person;
_personLoaded = true;
Interlocked.Decrement(ref isBusyCounter);
});
(The use of Interlocked
is needed since you're modifying the value on multiple threads, and this ensures that the updates don't conflict with each other; we don't care about order, since you'll end up with the same value whether one happens first or the other)
Then, rather than just checking IsBusy
, check IsBusy > 0
. The variable needs to be volatile
so that subsequent reads of the variable within a method don't get optimized away (in other words, if you're checking this condition in a loop or multiple times within a given function, then we put volatile
there to ensure that the value is checked each time rather than being cached locally).
Upvotes: 3