简体   繁体   中英

How to persist a webservice reference instance in an SQLCLR stored procedure?

At the moment I have a windows service written in C# that waits for a message in SQL Server Service Broker, and upon receipt calls a webservice method with details passed in the message.

I want to replace this with an SQLCLR stored procedure that calls the webservice directly, which I've found to be quite simple. I can then call this using internal activation.

However it needs to create a new instance of the webservice for each method, and from experience I've found this takes some time. In the windows service I create it with lazy instantiation in a static class, but I understand static fields can't be used to store information in SQLCLR.

Is there a way to persist this webservice reference?

Edit: Here is the lazy instantation code referencing the singleton I'd like to persist:

static class WsSingleton
{
    static MWs.MWS mWS = null;

    public static MWs.MWS GetMWS()
    {
        if (mWS == null)
        {
            mWS = new MWs.MWS();
            mWS.Credentials = new System.Net.NetworkCredential("user", "password", "domain");
        }
        return mWS;
    }
}

it needs to create a new instance of the webservice for each method

Do you mean the client has to instantiate a proxy for each HTTP call it makes? If that's what you mean you shouldn't have to persist any reference. An internal activated procedure is launched when there are messages to process and it can stay active and running. Such a locl state could be the proxy instance used to place the WWW calls. Typically the procedure runs a loop and keeps state on the stack as local variables of loop method. See Writing Service Broker Procedures for more details. To be more precise, your code should not RECEIVE one message at a time, but a set of messages.

But I would advise against doing what you're doing. First and foremost, making HTTP calls from SQLCLR is a bad idea. Doing any sort of blocking in SQLCLR is bad, and doing blocking on waiting for bits to respond from the intertubez is particularly bad. The internal SQL Server resources, specially workers , are far too valuable and few to waste them waiting for some WWW service to respond. I would advise keeping things like they are now, namely have hte HTTP call occur from an external process.

A second comment I have is that you may be better of using a table as a queue. See Using tables as Queues . One typical problem with queueing HTTP calls is that the WWW is very unreliable and you have to account for timeouts and retries. Using a table as a quueu can achieve this easier than a true Service Broker Queue. With SSB you'd have to rely on conversation timers for reliable retries, and it makes your activation logic significantly more complicated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM