I need to call a 3rd party web service from within a console application using the asynchronous method provided by their API. I'm using the old ASMX web reference way to generate a proxy.
I have a class that does the following operations and I want to create an instance of it, make the call to the service with it, but then I want to wait for the completion of the callback and only then repeat with a new instance, new call, new callback etc.
I do not want to have more than 1 call active at a time.
i.e. only 1 instance of the class will exist at a time.
The web service calling code looks like this:
using(ABCWebService service = new ABCWebService())
{
...
service.ExecuteCallAndWaitResultCompleted += service_ExecuteCallAndWaitResultCompleted;
service.ExecuteCallAndWaitResultAsync(parm1, parm2, .., stateObj);
}
...
The callback looks like this:
void service_ExecuteCallAndWaitResultCompleted(object sender, ExecuteCallAndWaitResultCompletedEventArgs e)
{
// collect data and then move onto next sequential call
}
I highly doubt there is an "asynchronous method provided by [the] API". A web method is a web method. It's your call which is asynchronous, that is to say by calling an async function on your client proxy class you tell the Framework to (in basic terms) fire off a request to this resource on another thread and call you back when it has a result. Its your client call which is asynchronous.
In Visual Studio (2012), when you Add Service Reference and then click Advanced and then Add Web Reference to create a service reference based on what VS calls "code based on .NET Framework 2.0 Web Services technology", which I gather is how you've done it, the resultant client class has not just asynchronous methods for each web method but synchronous methods too - one for each web method in the service. These synchronous methods will not return anything or yield control back to the caller until they have the result.
If I have your usage case correct, you want your console app to call the web method, wait for a response, do something once the responses arrives, and then start again. In that case, instead of calling the async method (for example GetPeopleAsync) call the synchronous method (GetPeople) - possibly inside a loop.
Related
I have a third-party web service that I need to call from the controller in my ASP.NET MVC application. I added a service reference to the provided WSDL and got everything running, but it turns out that the web service takes a very long time to complete (60+ seconds).
I have to create a client and monitor the status of that client in order to determine when the service is complete. According to their sample code, it should look something like this:
using (var client = new WebServiceClient())
{
// Omit all irrelevant client setup...
client.Process();
while (client.Status == "Processing")
System.Threading.Thread.Sleep(1000);
// The call is finished and the values in the client are now useable...
}
This works, but I hate tying up a thread for however long it takes to complete in a production website. Does anyone have any suggestions for a better way to handle this?
You should offload this to an external process. You can use something like Hangfire to fire off the task to be completed by something like a console app. Then, you can monitor the status of the job via long-polling or server push via SignalR. Your main website action just fires and forgets the job and quickly returns a response. The returned webpage, then, would use AJAX or Web Workers (in conjunction with SignalR on the server-side) to check on the status of the job and display progress to the user as updates are available.
See: http://docs.hangfire.io/en/latest/background-processing/tracking-progress.html
I deployed my service within a self hosted (OWIN) ASP.NET Web API:
config.Services.Replace(typeof(IHttpControllerTypeResolver), new MyHttpControllerTypeResolver());
Because of some changes in the underlying system I would like to reinitialize the service (singleton; instance of MyHttpControllerTypeResolver). Is this possible?
Without seeing how your application is structured, I'll assume the line of code you posted is in a method called Configuration belonging to a class called Startup (or similar), and that somewhere something is calling WebApp.Start<Startup>(...).
Configuration is sort of a "magic" method name that WebApp.Start will look for and call. WebApp.Start returns an IDisposible. In order to re-initialize things, you'll need to capture that IDisposible in some variable (let's call it app), call app.Dispose(), and then call WebApp.Start again.
I'm using an external open source project that provides me computation services that I create using a UI that it provides.
The project creates web-service endpoints automatically that I'm suppose to consume via my application.
My problem is that I can't interfere in the process. It's a black box that creates a service for me when I choose to deploy the project.
Each service has a bunch of different logical "private methods" that are exposed in the wsdl that's automatically created.
If I could create the service myself, I would create one an interface with an exposed method called Process that will have one general input request param and one general Response, something like:
public GeneralResponse Process(GeneralRequest request);
I want to create a generic out-point in my application which passes two parameters:
1.Endpoint Url to shoot the request to.
2.Generic request as an input param.
I'm using C# and the easiest way to consume a service is simply adding a service-reference, creating a client and calling the wanted method.
Since I don't want to add a client per service reference, I'll add a random one, change the client's endpoint address and shoot the request.
The problem with this approach is that the client generated will expose it's "private methods" and I don't want other programmers on my team to accidentally invoke them.
Bottom line:
Is there any elegant way to create a Generic soap client and invoke a method using a string? Similar to the way you call the Invoke method when you use reflection?
Something like this:
GenericRequest req = GetRequest();
SoapClient client = new SoapClient(endpointUrl);
GenericResponse res = client.Invoke("Process", req) as GenericResponse;
I have a web service with a import function i want to call from a c# application on another server
how do i call it
I can go to this url to invoke it:
http://site.co.uk/bespoke/WebService.asmx/Import
i want to call it from within my service on start:
protected override void OnStart(string[] args)
{
//What do i do in here?
}
You should use the Add Service Reference feature.
Your web service seems to be a SOAP service. So if you wanted to call it "manually" (without any SOAP client libraries), you would have to manually implement the protocol-level stuff (such as XML-based SOAP envelope). This is highly discouraged.
If you use the feature I mentioned above, then Visual Studio will generate classes and objects for you, so you will be able to call the web service's method via a method on a local stub class.
Are web service calls synchronous or asynchronous by default? How is synchronicity determined, by the service or by the client?
I have code similar to the following:
try
{
string result = MakeWebServiceCall_1(); // this is a third party webservice
MakeWebServiceCall_2(result); // another webservice which must happen *after* the first one is complete
}
catch()
{
SetStatus(Status.Error); // this calls my own stored procedure
throw;
}
SetStatus(Status.Sucess);
In the above, SetStatus is writing to the same tables that the third party web services read from. If I change the status before both web service calls have completed, it's going to make a big mess and I'm going to get fired. How do I know/ensure that the webservice calls are synchronous?
According to MSDN when you add a reference to a Web Service it will implement methods to call the Web Service both synchronously and asynchronously in the proxy class. You just need to make sure you call the right one.
After you have located an XML Web service for your application to access by using the Add Web Reference dialog box, clicking the Add Reference button will instruct Visual Studio to download the service description to the local machine and then generate a proxy class for the chosen XML Web service. The proxy class will contain methods for calling each exposed XML Web service method both synchronously and asynchronously. Source