views:

59

answers:

2

I know this has been addressed before but I have service that returns a string like so.

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class MyService : System.Web.Services.WebService
{

    [WebMethod]
    public string Hello()
    {
        System.Threading.Thread.Sleep(10000);
        return "Hello User";
    }
}

I've read many examples that say I need to call the method like this:

        MyService my = new MyService();
        AsyncCallback async = new AsyncCallback(callback);
        my.BeginHello();
        Console.WriteLine("Called webservice");

The thing is when I added reference I coudn't get the BeginHello method. All I saw was the HelloAsync. So I used it like this in my console app.

        MyService my = new MyService();
        AsyncCallback async = new AsyncCallback(callback);
        my.HelloAsync();
        Console.WriteLine("Called webservice");

and defined a private callback method like this

    private void callback(IAsyncResult res)
    {
        Console.Write("Webservice finished executing.");
    }

In doing so, I get an error like this:

An object reference is required for the non-static field, method, or property 'AsyncWebserviceCall.Program.callback(System.IAsyncResult)

Why dont I get the BeginHello method & Why do I get this error as above?

Thanks for your time.

+3  A: 

If the code is being run inside your public static void Main(string[] args) function then you need to make private void callback(IAsyncResult res) a static method:

private static void callback(IAsyncResult res)
{
    Console.Write("Webservice finished executing.");
}

That's why you're getting that error.

From ASP.NET 2.0 onwards there were some changes to how you make async web service calls. Do this instead:

MyService my = new MyService();
my.HelloCompleted += CallBack;
my.HelloAsync();
Console.WriteLine("Called service.");
Console.ReadLine();  // Wait, otherwise console app will just exit.

Your callback method signature changes to:

private static void CallBack(object sender, HelloCompletedEventArgs e)
{
    Console.WriteLine("Webservice finished executing.");
}

More info:

From Visual Studio 2005 onwards the Add Web Reference proxy generator no longer creates the BeginXXX/EndXXX methods. These methods were deprecated in favour of the XXXAsync/XXXCompleted pattern.

If you really need to work with the BeginXXX/EndXXX style async methods you can use one of the following methods:

  1. Use the WSDL.exe tool to create the proxy. For example:

    wsdl.exe /out:MyService.cs http://somedomain.com/MyService.asmx?wdsl

    Include the generated MyService.cs file in your project and use that instead of a Web Reference. You need to open a Visual Studio command prompt for this so that the .NET Framework SDK binaries are in your path.

  2. There is apparently a hack in Visual Studio (it may no longer be available). For more info see this MS Connect case:

Begin/End Async WebService Proxy Methods Not Generated in Web Application Projects

My advice would be to embrace the new approach.

Kev
Thanks. That solved one problem. what about the missing BeginHello method?
Thanks Kev. so you're saying that ASP.NET 2.0 onwards they removed the {Begin...} prefix to async calls?
I dont think this line will work: my.HelloCompleted += CallBack; I will add an aswer shwoing what I did that got it working. Meanwhile how does this guy have both methods available? http://www.codeproject.com/Articles/70441/Calling-Web-Service-Functions-Asynchronously-from-.aspx
+1  A: 

Here is what I changed on the client side to get it working.

    static void Main(string[] args)
    {
        MyService my = new MyService();
        my.HelloCompleted +=new HelloCompletedEventHandler(my_HelloCompleted);
        my.HelloAsync();
        Console.WriteLine("Called webservice");
        Console.ReadKey();

    }

    private static void my_HelloCompleted(object sender, HelloCompletedEventArgs e)
    {
        Console.Write("Webservice finished executing in my_HelloCompleted.");
    }
Glad you got it working. :) From C#2.0 onwards you don't need to specify the `new HelloCompletedEventHandler`. Just do: `my.HelloCompleted += my_HelloCompleted`.
Kev
Thanks Kev. Will try that out. :)