Shared Static data in CLR without UNSAFE?

  • Here's a really cool tip that I just heard from Remus Rusanu: Apparently, you can use the CompilerGenerated decoration to allow Static Shard data in a CLR without requiring the UNSAFE permission set. I suspect that this use is not supported though ... 🙂

    [font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
    Proactive Performance Solutions, Inc.
    [/font]
    [font="Verdana"] "Performance is our middle name."[/font]

  • Hi Barry!

    Thanks for the tip. Another way to handle this is a "static readonly" field which represents a wrapper for the real object ;-).

    Here's a little sample:

    class StaticWrapper

    {

    public StaticWrapper(T value)

    {

    Value = value;

    }

    public StaticWrapper()

    {

    Value = default(T);

    }

    public T Value { get; set; }

    }

    private static readonly StaticWrapper _myStatic = new StaticWrapper();

    [Microsoft.SqlServer.Server.SqlFunction]

    public static SqlXml ufn_clr_test()

    {

    _myStatic.Value = "Blah";

    return new SqlXml();

    }

    Greets

    Flo

  • It's still not thread safe, either way you hook it, which is why MSFT deemed that code implementing that would require UNSAFE rights because your value isn't guaranteed.

    Jonathan Kehayias | Principal Consultant | MCM: SQL Server 2008
    My Blog | Twitter | MVP Profile
    Training | Consulting | Become a SQLskills Insider
    Troubleshooting SQL Server: A Guide for Accidental DBAs[/url]

  • Hi Jonathan

    Sure, my sample is not thread safe. It was just a sample how to add static fields into a CLR function. To get it thread safe you can use thread safe base classes.

    Greets

    Flo

  • Florian Reischl (8/27/2009)


    Hi Jonathan

    Sure, my sample is not thread safe. It was just a sample how to add static fields into a CLR function. To get it thread safe you can use thread safe base classes.

    Greets

    Flo

    At that point you have consistency but with blocking in the CLR layer as the trade off. I guess I just haven't found a good enough use for a static variable that is editable in SQLCLR yet.

    Jonathan Kehayias | Principal Consultant | MCM: SQL Server 2008
    My Blog | Twitter | MVP Profile
    Training | Consulting | Become a SQLskills Insider
    Troubleshooting SQL Server: A Guide for Accidental DBAs[/url]

  • Well, I sure haven't had any trouble coming up with reasons for shared static data: it's the only way I know of to keep any kind of context across calls reliably. Mind you, not IN the shared static field itself, you keep the contextual data in dynamic structures, segregated by your contexts, but you need a fixed global starting point that can't be lost in order for that to work.

    Of course there's many downsides to this kind if approach as it's basically just a manual kludge to emulate our own class and thread contexts. Then there's the blocking issues that Jonathan mentions: they don't have to be bad, because you really only have to block on the shared static filed and it's contained structure, but not on their contents once you find them, but still , you've got to do it on every entry. And finally, including that you have to label your assemblies with UNSAFE which at a minimum always means a special meeting before deployment in order to justify it.

    The irony is that the only reason that we need to do all of this sneaking around behind the SQLOS's back in the first place is because it doesn't provide us with what we really want: Session, Request (Batch), and Invocation context handles/pointers, etc.

    (now I'll let all of the people here who know a lot more about this than I do correct me ... :-)).

    [font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
    Proactive Performance Solutions, Inc.
    [/font]
    [font="Verdana"] "Performance is our middle name."[/font]

  • RBarryYoung (8/27/2009)


    Well, I sure haven't had any trouble coming up with reasons for shared static data: it's the only way I know of to keep any kind of context across calls reliably. Mind you, not IN the shared static field itself, you keep the contextual data in dynamic structures, segregated by your contexts, but you need a fixed global starting point that can't be lost in order for that to work.

    This is where things can get really dicey though. Let say you have this state/context information stored and between calls, your AppDomain gets unloaded for memory pressure. It can certainly reload, but you are going to lose the shared contextual data in the process. This is just one problem I can think of that would be of concern with this. (BTW, this was actually pointed out to me as a problem by UC at Microsoft at PASS summit last year while I was picking his brain about AppDomain Unloads, I am not smart enough to have though of it on my own.)

    Jonathan Kehayias | Principal Consultant | MCM: SQL Server 2008
    My Blog | Twitter | MVP Profile
    Training | Consulting | Become a SQLskills Insider
    Troubleshooting SQL Server: A Guide for Accidental DBAs[/url]

  • Yep, but AppDomain unloads are a serious problem for lots of things. If you take away my context and don't give it back then I will fail and throw an error. I think that you'll find that lots of stuff in SQL works that way, including a lot of Microsoft's stuff. Solution: run it again.

    Granted, I wish it weren't that way, but this is what MS has given us, and until they give us something better (or fix this), then we either use it or we don't.

    [font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
    Proactive Performance Solutions, Inc.
    [/font]
    [font="Verdana"] "Performance is our middle name."[/font]

  • RBarryYoung (8/27/2009)


    until they give us something better (or fix this), then we either use it or we don't.

    Now you know that is just an open door for Jeff Moden right? 🙂

    Jonathan Kehayias | Principal Consultant | MCM: SQL Server 2008
    My Blog | Twitter | MVP Profile
    Training | Consulting | Become a SQLskills Insider
    Troubleshooting SQL Server: A Guide for Accidental DBAs[/url]

  • Static/shared contexts can be used for tasks where they are useful for but are not required within a function/procedure.

    Sample:

    Compiled Regex is much faster than a not compiled, but the compilation takes its time. You can use a dictionary to store Regular compiled regular expressions within. Whenever you call the function you try to get an existing compiled expression for the specified pattern from your context. If it does not exist you create a new compiled expression and store it within the dictionary.

    .NET 4.0 introduces a new parallelism namespace, if I'm correct they also add some build-in thread safe collections which simplify the collection handling.

Viewing 10 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic. Login to reply