Page Methods
As of late several things have been calling my attention to get back into JavaScript, most especially in the area of AJAX. Through colleagues and friends I've been introduced to a lot of the popular standards right now, which all seemed to follow the patterns I expected, but there were some things that I payed extra homage to. Most notably, I really enjoy the concept of Page Methods. If you haven't used them yet, Page Methods allow you to define a static WebMethod in the class for an ASP.NET Page and expose them to client script. ScriptManager.EnablePageMethods adds the convenience of generating a proxy to access the method from client script with little hassle, though it turns out the property isn't needed to call the service, it only generates client script for you (probably based on reflection of the page, though I haven't checked into this yet). With some further reading (due to a nod from a colleague) I found Dave Ward's post on using jQuery to directly call ASP.NET page methods. All was well and good... until that curiosity kicked in.
Encapsulation
One of my favorite things about Page Methods is that it allows the logic for asynchronous calls to be grouped in the same body of code that it pertains to. Just as I define event handlers for oldschool postbacks in the page, I can also define the callbacks used by a page there. There are some other differences worth noting, such as a slimmer service model since no WSDL is necessary and only JSON is supported, which can arguably be considered a performance optimization, but ultimately (as an engineer) the encapsulation is what really draws me to this design.
Control Methods
After appreciating the value of being able to call a service whose definition is within the page, one thing that seems to be common is for people to try to do the same within a UserControl. It seems like a great idea to be able to implement reusable AJAX controls keeping the logic contained within the code it relates to. This is especially noteworthy when the asynchronous call is specific to the logic of the control; currently most controls use .asmx web services, which makes sense, especially if a web service will be reused, but all-in-all, seems a mite overboard for some particular control's one-off auto-complete list or the like and, additionally, it unnecessarily complicates organization and maintenance efforts. Unfortunately, as many others have commented, this feature is not supported for methods within a UserControl. When looking into how web services are provided in ASP.NET it seemed to be an unnecessary limitation; true .ascx extensions are, by default, handled by the HttpForbiddenHandler, but Page Method requests shouldn't be (and as research indicates, aren't) handled by PageHandlerFactory or the Page class; the methods are static and initializing the page's object model would defeat the purpose of using real web services instead of UpdatePanel (for those that are less familiar with the life-cycle of a page and why this would be less efficient, this is a good starting point). To me, this implied that the handling of these methods only required a static method marked with some attributes to exist within a class accessible by the web application; the rest was a matter of translating the request into the right calls.
Enter ScriptModule. ScriptModule is configured in Web.config for all ASP.NET AJAX projects. It seems to facilitate a few things, though I didn't look into much detail as my only concern was with the handling of Page Methods. As it turns out, the limitation is strictly superficial; ScriptModule explicitly checks that the current request is a Page before doing anything related to a REST query.
ScriptModule has a very simple process for handling Page Methods and the implementation details were really handled in classes and static methods that received relative paths and method names as string parameters. Perfect! I should be able to reuse the existing implementation after changing little of the request parsing... right? Wrong. Unfortunately all of the helper classes and methods are marked internal so there is no easy way to access the existing functionality. Alas, I really like the idea of encapsulating my control logic in my control class. It would probably be possible to rewrite the implementation, or more suitable for Microsoft to modify the module to handle a few more cases (they could actually modify a few things, like the convenience code generation and properties for Extenders), but for the time being I have settled on creating a solution that used the same implementation as Page Methods through Reflection.
Reflection
The downside to using reflection in this solution is that typical ASP.NET security models do not allow much reflection. Some trust levels provide limited reflection permission, but invoking internal members of an assembly is forbidden as a security measure in all of the default security levels short of Full Trust (which is not ideal for production environments). The other levels can be modified to support ReflectionPermission, but ultimately the rule is in place for a reason. That said I've created two methods to access Control Methods. One is an in-application ashx handler that would require the above-mentioned security modifications, but is rather simple to drop in. The other (recommended) option is an IHttpModule contained in a strong-named assembly registered in the Global Assembly Cache. By default, assemblies in the GAC are granted full trust, even in web applications, so the module can serve Control Methods without compromising the security of the web application.
Source
Since it seems like other people are interested in this as well, I've posted my implementation of Control Methods for ASP.NET AJAX to CodePlex under a BSD style license. It's not a priority of mine, but I do intend to further extend this to support the same functionality for Master Pages as well as trying to test interaction with various AJAX Server Controls (like AutoCompleteExtender). I have not tested standard ASP.NET authorization and security methods extensively yet either. Still, the design model is good, and maybe this will call some attention to the desire for this functionality to get some official support.
Monday, January 18, 2010
Thursday, December 17, 2009
Reborn a Princess?
A Roller Coaster Wridden by the Mad Hatter Jason
With clear vantage he stands upon the mount,
atop the apex of his being, surveying things one can't count.
The valleys down below echo in chorus
telling grand stories with messages amorous
and tales of nearing epoch on his account.
Observantly, he sits in wait, ever curious
listening for the hints his future may recount.
With battlefield ballads of heart mind and soul,
intermixing melodies of each of his goals.
All well defined, he's in complete control
yet stagnant he waits, debating his role.
Two melodies at war with none to console
and a third sonorously resonating; amplifying the whole.
His empire is forming, of this he is sure,
yet he takes no claim 'til his aims be secure.
Seeking solace in heart with expression that's pure,
slows the acquisition of success for this entrepreneur.
All the while fulfilling potential could be the cure,
but should he be satisfied trailing money as his spoor
or ensure his pursuit is not drawn by this allure.
His potential laid before him, illusory confusion disbanded;
his castle's not built yet and so he must move forward.
Yet in timely fashion, significance of other tunes expanded
the melodious infusion becomes less obscure yet carries no reward.
Instead he listens to lonely tones, once again standing stranded.
Alas, music to his ears, the notes begin to harmonize.
Finally a path appears wherein a symphony might form,
in front of him doth his heart's song materialize
such radiantly burning melody with no care for the norm;
peering past words he doesn't intend to idealize
but rather knows full well that he seeks the perfect storm
if only the efforts of happiness would make her realize.
He observes as her journey takes the fashion like Ulalume,
veiled like a raven beguiling her sad fancy into smiling,
as she again unknowingly travels to her lost love's tomb
and he hopes that her off-putting words are of like styling.
Reinforcing stone walled heart with her soul's intense fire,
she's managed to postpone his last sought desire;
though she shields her cloaked heart, his thoughts do not tire
instead against her voiced motive, the challenge doth inspire.
He can't help but notice melodic lines from her luminous lyre;
the tonal pattern of a child's pure joy that elates the young sire
empowering him to withstand her psyche's blazing pyre.
Crazy love shrouds him as burnt landscape doth form
and when the dance gets hot he does not hide or mourn.
He simply waits wishing for the honor to see the phoenix reborn
With clear vantage he stands upon the mount,
atop the apex of his being, surveying things one can't count.
The valleys down below echo in chorus
telling grand stories with messages amorous
and tales of nearing epoch on his account.
Observantly, he sits in wait, ever curious
listening for the hints his future may recount.
With battlefield ballads of heart mind and soul,
intermixing melodies of each of his goals.
All well defined, he's in complete control
yet stagnant he waits, debating his role.
Two melodies at war with none to console
and a third sonorously resonating; amplifying the whole.
His empire is forming, of this he is sure,
yet he takes no claim 'til his aims be secure.
Seeking solace in heart with expression that's pure,
slows the acquisition of success for this entrepreneur.
All the while fulfilling potential could be the cure,
but should he be satisfied trailing money as his spoor
or ensure his pursuit is not drawn by this allure.
His potential laid before him, illusory confusion disbanded;
his castle's not built yet and so he must move forward.
Yet in timely fashion, significance of other tunes expanded
the melodious infusion becomes less obscure yet carries no reward.
Instead he listens to lonely tones, once again standing stranded.
Alas, music to his ears, the notes begin to harmonize.
Finally a path appears wherein a symphony might form,
in front of him doth his heart's song materialize
such radiantly burning melody with no care for the norm;
peering past words he doesn't intend to idealize
but rather knows full well that he seeks the perfect storm
if only the efforts of happiness would make her realize.
He observes as her journey takes the fashion like Ulalume,
veiled like a raven beguiling her sad fancy into smiling,
as she again unknowingly travels to her lost love's tomb
and he hopes that her off-putting words are of like styling.
Reinforcing stone walled heart with her soul's intense fire,
she's managed to postpone his last sought desire;
though she shields her cloaked heart, his thoughts do not tire
instead against her voiced motive, the challenge doth inspire.
He can't help but notice melodic lines from her luminous lyre;
the tonal pattern of a child's pure joy that elates the young sire
empowering him to withstand her psyche's blazing pyre.
Crazy love shrouds him as burnt landscape doth form
and when the dance gets hot he does not hide or mourn.
He simply waits wishing for the honor to see the phoenix reborn
Thursday, August 27, 2009
Mimsy's Box
A mental delicacy prepared in race fashion by none other than the Mad Hatter Jason.
She pierces him with eyes of fire,
Revs her engine and spins her tires,
In hot pursuit he chases her,
Finding her lines, each hidden curve,
He gently follows her snaking path,
Learning more at every pass.
All is fun and the race goes fast,
When suddenly his chase doth crash!
An earth-shaking tremor of doubt,
Second guesses run rampantly,
Guiding a guilt-based inner bout,
He worries about her safety,
But next thing he knows she starts to burn out.
Again he gives chase
To see her pretty face
But down the road discovers
This time’s not a race.
She flees the scene to keep him safe
And frees the man from awful fate
But thinks not how his heart might shake
‘Til face to face they meet beside a lake.
He reads the surface of her mind,
Proving out loud that it’s clear as day,
But when he wonders what he’ll find,
When digging deeper, and what she’ll say.
In the realm of sanity,
He starts to play,
With words like a hatter,
His madness on display.
Down the rabbit hole he lives,
Beckoning her further so he might give
Insight of healing and thoughts curative.
A young Alice, she wavers at the small door,
To a world that is meaningless and yet means so much more.
Unmoving she stands debating the vial,
Wondering how insanity will help her survival.
And thus the hatter speaks,
Explaining his world,
Describing what he sees,
The girl’s being unfurled.
"An angel stuffed in a box labeled 'DO NOT OPEN. EVIL' guarded by a selfish girl shrouded in a thin cloak of innocence imagining a dark cloud of guilt overhead."
He says, then details what he wants instead.
Why oh why, won’t you be nicer to yourself and me,
I can’t wait to see inside Mimsy.
Around the question the rabbit dances,
With no meaning given, a short reply she answers
Smiling she prances "Uhuh... we’ll see."
Seeing her fence, he lures her in
To break her defense of the question
He simply states rather exactly
I’m not sure you know what’s in the box, my dear mimsy.
In playful response she takes the poke,
Inside the box? Hmm… nope
Well milady Mimsy, what remains is called "Hope."
Not wanting to hurt, or be hurt in kind,
She ignores his advances time after time.
She says she needs easiness (so she can drive blind),
But he knows it’s a challenge that will make her sublime.
Discussing Pandora and history past,
He tells her of differences between the easy and right paths.
Alas, if only Mimsy were the Borogoves,
And the past would find its tears,
The hatter could hap happiness,
And destroy all her fears.
The psycho semantic and curious chef,
To the best of his skills with which he’s been blessed
He composes tenuously a meal of mental obscurity,
With such delicious components, an epicurean rarity
And simplistic appearance on which she can dine
Where the residual flavor improves over time.
Finally she opens her heart to his mind,
Even if only a piece at a time,
Alas his chance has finally arrived,
To be such a happy Mad Hatter that he composes this rhyme.
This is a poem I wrote not long ago. I'm very pleased with the way it turned out (the poem, not so much the rest of the story, lol) and have kept it quietly stashed amongst close friends, but I'm so very fond of this poem and have little reason to keep it locked up, so I thought I would share it with the world. There are many reason's I'm happy with this work, some which will not be perceived by anybody, some that only a select few will understand, but for the rest of you, I'm quite happy with two things primarily: First, I wrote this from beginning to end with no backtracking, proof reading or editing (Edit: I added the subtitle when I finished). Second, is my application of the term "mimsy," originally coined by the great author Charles Lutwidge Dodgson (better known as Lewis Carroll), whom I have a great deal of respect and admiration of. Mimsy, in this work, is a person to whom, at the time in my mind's eye, both Carroll's initial meaning of the word, as well as the additional meaning and context added over the years. At any rate, do enjoy. I'm interested in feedback too, though it's unlikely that I will edit the work at all, considering the circumstances.
She pierces him with eyes of fire,
Revs her engine and spins her tires,
In hot pursuit he chases her,
Finding her lines, each hidden curve,
He gently follows her snaking path,
Learning more at every pass.
All is fun and the race goes fast,
When suddenly his chase doth crash!
An earth-shaking tremor of doubt,
Second guesses run rampantly,
Guiding a guilt-based inner bout,
He worries about her safety,
But next thing he knows she starts to burn out.
Again he gives chase
To see her pretty face
But down the road discovers
This time’s not a race.
She flees the scene to keep him safe
And frees the man from awful fate
But thinks not how his heart might shake
‘Til face to face they meet beside a lake.
He reads the surface of her mind,
Proving out loud that it’s clear as day,
But when he wonders what he’ll find,
When digging deeper, and what she’ll say.
In the realm of sanity,
He starts to play,
With words like a hatter,
His madness on display.
Down the rabbit hole he lives,
Beckoning her further so he might give
Insight of healing and thoughts curative.
A young Alice, she wavers at the small door,
To a world that is meaningless and yet means so much more.
Unmoving she stands debating the vial,
Wondering how insanity will help her survival.
And thus the hatter speaks,
Explaining his world,
Describing what he sees,
The girl’s being unfurled.
"An angel stuffed in a box labeled 'DO NOT OPEN. EVIL' guarded by a selfish girl shrouded in a thin cloak of innocence imagining a dark cloud of guilt overhead."
He says, then details what he wants instead.
Why oh why, won’t you be nicer to yourself and me,
I can’t wait to see inside Mimsy.
Around the question the rabbit dances,
With no meaning given, a short reply she answers
Smiling she prances "Uhuh... we’ll see."
Seeing her fence, he lures her in
To break her defense of the question
He simply states rather exactly
I’m not sure you know what’s in the box, my dear mimsy.
In playful response she takes the poke,
Inside the box? Hmm… nope
Well milady Mimsy, what remains is called "Hope."
Not wanting to hurt, or be hurt in kind,
She ignores his advances time after time.
She says she needs easiness (so she can drive blind),
But he knows it’s a challenge that will make her sublime.
Discussing Pandora and history past,
He tells her of differences between the easy and right paths.
Alas, if only Mimsy were the Borogoves,
And the past would find its tears,
The hatter could hap happiness,
And destroy all her fears.
The psycho semantic and curious chef,
To the best of his skills with which he’s been blessed
He composes tenuously a meal of mental obscurity,
With such delicious components, an epicurean rarity
And simplistic appearance on which she can dine
Where the residual flavor improves over time.
Finally she opens her heart to his mind,
Even if only a piece at a time,
Alas his chance has finally arrived,
To be such a happy Mad Hatter that he composes this rhyme.
This is a poem I wrote not long ago. I'm very pleased with the way it turned out (the poem, not so much the rest of the story, lol) and have kept it quietly stashed amongst close friends, but I'm so very fond of this poem and have little reason to keep it locked up, so I thought I would share it with the world. There are many reason's I'm happy with this work, some which will not be perceived by anybody, some that only a select few will understand, but for the rest of you, I'm quite happy with two things primarily: First, I wrote this from beginning to end with no backtracking, proof reading or editing (Edit: I added the subtitle when I finished). Second, is my application of the term "mimsy," originally coined by the great author Charles Lutwidge Dodgson (better known as Lewis Carroll), whom I have a great deal of respect and admiration of. Mimsy, in this work, is a person to whom, at the time in my mind's eye, both Carroll's initial meaning of the word, as well as the additional meaning and context added over the years. At any rate, do enjoy. I'm interested in feedback too, though it's unlikely that I will edit the work at all, considering the circumstances.
Friday, August 7, 2009
TechVi: Zune Development with XNA
First and foremost, I want to thank the gents over at TechVi for inviting me to contribute to their program. It's always nice to work with a bunch of smart and driven folks. That said, as I just came on board today I was going through some of the previous shows to see what I was getting into. As I was taking a peak at the recent ZuneHD spot some comparison between the iPod Touch/iPhone caught my attention with the mention of application development on the Zune, which came across as a rather bleak outlook. I just wanted to point out some of the things Microsoft has been working on to that regard to give a little more clarity.
To be clear, I'm no expert with the Zune (my Touch Pro is a perfectly sufficient MP3 player for me), nor am I personally up to date with the development technologies I'll be pointing out. I have, however, been watching Microsoft's strategy for many years as they've moved forward and I have my own hypothesis to make about the future of development in this regard. Now, to the point:
Over the last few years Microsoft's .NET Framework has been gaining a lot of ground in the development industry. One of it's challenges early on was that, while well designed for desktop and web applications, it was not prepared for one of the most sought after markets in the technology industry: games. Those of us who were knee deep in trying to figure out ways to make good games while still leveraging the power of .NET during these early days may even remember Microsoft releasing an unsupported Managed wrapper for DirectX with the DirectX SDK. Not long after (but long enough for plenty of us to have started dabbling with it) they yanked the good stuff right out from under us. Turns out Microsoft was moving to a new platform altogether. Enter XNA (the clever buggers went and took the recursive acronym to a new level, XNA stands for "XNA is Not an Acronym"). It started a bit rough, but, as with any other Microsoft development technology, ultimately turned out to be generally viewed as really well planned with great tools and a lot of opportunity ahead.
Since it's mention in 2004, XNA Game Studio is up to version 3 and now offers 2D and 3D game development support and runs, in some capacity or another, on Desktop PCs, XBOX 360, and Zune. The platform is based on a modified version of the .NET Compact Framework which is a reasonably capable and very easy to use development platform that facilitates a powerful, easy to read/write, well organized environment. Using this technology it is possible to develop a game that will run on all three platforms with little to no change in the code. In order to leverage this to compete with Apple's App Store it may be necessary for Microsoft to rethink their distribution model (currently they offer a paid subscription only designed for XBOX 360), but as a development platform it is very clean, easy to use and powerful.
I don't know what Microsoft intends to do about distribution, but I can at least speculate on one more change that seems innevitable for the future. Early on the intention to support Windows Mobile devices with XNA alongside the XBOX and Desktop PC seemed obvious, though over time have faded from memory. Zune managed to get in the door first, but I still see the handheld OS now commonly found on phones in XNA's near future. I've been toying with Windows Mobile 6.5 and an unreleased version of the NetCF runtime (listed currently as version 3.7). One of the first things I noticed while playing with the new runtime is that it no longer includes the mobile Managed DirectX library. Some speculate that it's because OpenGLES is so dominant in the portable industry, but this feels rather reminiscent of the last time they wanted to make a move to XNA. The Windows Mobile platform will be much harder to target than XBOX and Zune were because of the great variety of hardware that it runs on and their varying capabilities (much like the desktop version), but since XNA is based on the Compact Framework it seems like an innevitable move, leaving the bulk of my assumption on the "when" side. I guess now all we can do is wait and see.
To be clear, I'm no expert with the Zune (my Touch Pro is a perfectly sufficient MP3 player for me), nor am I personally up to date with the development technologies I'll be pointing out. I have, however, been watching Microsoft's strategy for many years as they've moved forward and I have my own hypothesis to make about the future of development in this regard. Now, to the point:
Over the last few years Microsoft's .NET Framework has been gaining a lot of ground in the development industry. One of it's challenges early on was that, while well designed for desktop and web applications, it was not prepared for one of the most sought after markets in the technology industry: games. Those of us who were knee deep in trying to figure out ways to make good games while still leveraging the power of .NET during these early days may even remember Microsoft releasing an unsupported Managed wrapper for DirectX with the DirectX SDK. Not long after (but long enough for plenty of us to have started dabbling with it) they yanked the good stuff right out from under us. Turns out Microsoft was moving to a new platform altogether. Enter XNA (the clever buggers went and took the recursive acronym to a new level, XNA stands for "XNA is Not an Acronym"). It started a bit rough, but, as with any other Microsoft development technology, ultimately turned out to be generally viewed as really well planned with great tools and a lot of opportunity ahead.
Since it's mention in 2004, XNA Game Studio is up to version 3 and now offers 2D and 3D game development support and runs, in some capacity or another, on Desktop PCs, XBOX 360, and Zune. The platform is based on a modified version of the .NET Compact Framework which is a reasonably capable and very easy to use development platform that facilitates a powerful, easy to read/write, well organized environment. Using this technology it is possible to develop a game that will run on all three platforms with little to no change in the code. In order to leverage this to compete with Apple's App Store it may be necessary for Microsoft to rethink their distribution model (currently they offer a paid subscription only designed for XBOX 360), but as a development platform it is very clean, easy to use and powerful.
I don't know what Microsoft intends to do about distribution, but I can at least speculate on one more change that seems innevitable for the future. Early on the intention to support Windows Mobile devices with XNA alongside the XBOX and Desktop PC seemed obvious, though over time have faded from memory. Zune managed to get in the door first, but I still see the handheld OS now commonly found on phones in XNA's near future. I've been toying with Windows Mobile 6.5 and an unreleased version of the NetCF runtime (listed currently as version 3.7). One of the first things I noticed while playing with the new runtime is that it no longer includes the mobile Managed DirectX library. Some speculate that it's because OpenGLES is so dominant in the portable industry, but this feels rather reminiscent of the last time they wanted to make a move to XNA. The Windows Mobile platform will be much harder to target than XBOX and Zune were because of the great variety of hardware that it runs on and their varying capabilities (much like the desktop version), but since XNA is based on the Compact Framework it seems like an innevitable move, leaving the bulk of my assumption on the "when" side. I guess now all we can do is wait and see.
Monday, April 6, 2009
Retry Oriented Thread Synchronization
Somewhat recently at work I've been troubleshooting some concurrency edge cases involving deadlocks due to thread synchronization. In my experience, a lot of times this is the result of creating lock objects for separate collections or something of the sort. In most of the code only one collection/object is accessed at a time and the separate synchronization objects allow for less contention and more throughput. Excluding simple/obvious mistakes, the problem typically arises when different code paths require the objects in opposite order, sometimes becoming more difficult to trace when they involve events/handlers. Obviously on goal when locking is to lock the synchronization object for as little time as possible, but sometimes it's simply necessary to hold a lock while entering an event or callback.
One solution, which worked fine for us, was to get rid of one of the synchronization objects and use the same one for both collections. Ultimately it was all that was necessary for our solution, since we couldn't change the other code paths or unlock one of the synchronization roots, but it did inspire me to start trying to think of a better solution. I've been toying with an idea somewhat similar to the pattern used by TransactionScope, taking advantage of the using statement to allow syntax to stay simple (since the lock statement is so lightweight it would be ideal to keep the new solution quick and easy). I certainly haven't found the ideal solution just yet, and it's quite likely that there really is no ideal solution, but I've posted the new code and test application on CodePlex, hoping others in the community will see the potential advantages and help me improve on it, either with code or ideas. This also doesn't implement any synchronization techniques regarding Mutexes, Semaphores, or any other wait handle style synchronization, this is currently specific to using Monitor and may only serve to improve circumstances using traditional lock statements or Monitor directly.
The general concept behind usage in the current implementation is as follows:
One thing I've already considered through the simple test application I've made is the possibility of adding support for prioritization based on retry counts, which could be useful, but since these are thread specific and this is supposed to be a lightweight class it may require the use of WeakReferences so I haven't gone through with it yet since I'm still working on finding other possibilities and it could wind up being a waste of effort. One problem mentioned above that this still doesn't solve is the event handler situation, where I lock a synchronization object important to me and then fire an event which can be attached to by arbitrary code; since I don't have control over both code-bases I can't see a means to provide any "let me get out of your way" logic, since we can't release the lock once synchronization-dependent code has already begun executing. I was thinking about the possibility of a delegate or delegate wrapper that carries a reference to the synchronization object would work for some occasions, but without some under-.NET's-hood voodoo it would still sacrifice syntax clarity/diversity, which I'm trying to avoid. It seems there will have to be a tradeoff somewhere in order to improve this model, and maybe using a single callback with a synchronization object reference instead of supporting a multicast delegate may be that answer, but for now I'm going to think on it more. I would really love any insight from those in the wilderness; I've certainly not been exposed to every method of using threads and synchronization and, while I'm pretty familiar with Monitor and other synchronization classes, there could still be something obvious I'm not privy too as well.
-TheXenocide
One solution, which worked fine for us, was to get rid of one of the synchronization objects and use the same one for both collections. Ultimately it was all that was necessary for our solution, since we couldn't change the other code paths or unlock one of the synchronization roots, but it did inspire me to start trying to think of a better solution. I've been toying with an idea somewhat similar to the pattern used by TransactionScope, taking advantage of the using statement to allow syntax to stay simple (since the lock statement is so lightweight it would be ideal to keep the new solution quick and easy). I certainly haven't found the ideal solution just yet, and it's quite likely that there really is no ideal solution, but I've posted the new code and test application on CodePlex, hoping others in the community will see the potential advantages and help me improve on it, either with code or ideas. This also doesn't implement any synchronization techniques regarding Mutexes, Semaphores, or any other wait handle style synchronization, this is currently specific to using Monitor and may only serve to improve circumstances using traditional lock statements or Monitor directly.
The general concept behind usage in the current implementation is as follows:
using (LoopLock l = new LoopLock(ltp.Syncs))The LoopLock constructor takes in a params array of all the synchronization objects (in the order they should be locked). The AcquireLock method only exists to allow attaching an event handler, which will be described in a moment. AcquireLock attempts to obtain a lock on each synchronization object one at a time. If it is unable to obtain any lock in 100ms (by default, though there is a constructor overload to provide the timeout period) it will proceed to unlock each of the successfully locked objects (in reverse order), fire the LockAttemptFailed event which provides the number of tries so far along with the option of aborting the process alltogether (which throws a LoopLockAbortedException). If all locks are acquired code will proceed and, when the code leaves the scope of the using statement, all locks are released (in the opposite order they were locked).
{
//optional event, but here for testing
l.LockAttemptFailed += new LoopLockEventHandler(delegate(LoopLock sender, LoopLockEventArgs e)
{
if (e.Attempts > 200)
{
//sample of aborting if it takes to long to get a successful lock;
e.AbortLock();
}
});
l.AcquireLock();
Thread.Sleep(rnd.Next(5490) + 20);
}
One thing I've already considered through the simple test application I've made is the possibility of adding support for prioritization based on retry counts, which could be useful, but since these are thread specific and this is supposed to be a lightweight class it may require the use of WeakReferences so I haven't gone through with it yet since I'm still working on finding other possibilities and it could wind up being a waste of effort. One problem mentioned above that this still doesn't solve is the event handler situation, where I lock a synchronization object important to me and then fire an event which can be attached to by arbitrary code; since I don't have control over both code-bases I can't see a means to provide any "let me get out of your way" logic, since we can't release the lock once synchronization-dependent code has already begun executing. I was thinking about the possibility of a delegate or delegate wrapper that carries a reference to the synchronization object would work for some occasions, but without some under-.NET's-hood voodoo it would still sacrifice syntax clarity/diversity, which I'm trying to avoid. It seems there will have to be a tradeoff somewhere in order to improve this model, and maybe using a single callback with a synchronization object reference instead of supporting a multicast delegate may be that answer, but for now I'm going to think on it more. I would really love any insight from those in the wilderness; I've certainly not been exposed to every method of using threads and synchronization and, while I'm pretty familiar with Monitor and other synchronization classes, there could still be something obvious I'm not privy too as well.
-TheXenocide
Subscribe to:
Posts (Atom)