質問

I am having a wcf service and I am calling a method like this:

public static void f5()
    {
        var client = new WebClient();
        client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted);
        var data = File.ReadAllText("request.xml");
        client.Headers.Add("Content-Type", "text/xml;charset=utf-8");
        client.Headers.Add("SOAPAction", "some string");            
        client.UploadStringAsync(new Uri("http://differentdomain/wcf/Service.svc"), data);
    }

    public static void client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
    {
        Console.WriteLine(e.ToString());
        int cow = 0;
        cow++;
    }

    static void Main(string[] args)
    {
        f5();
    }

This program works perfectly when I don't use async method however the handler is not getting called soe some reason. The web service is hosted on a different computer on a different domain but the client and server are connected to same network. Most importanly everything works fine if I use UploadString instead.

Thanks

役に立ちましたか?

解決

Your program is exiting right after the call to UploadStringAsync, so it doesn't have time to get the response. In the code below, if I remove the Thread.Sleep call at the end of the Main method, it will also not print anything. Try waiting for the response to arrive before exiting your program.

public class StackOverflow_11218045
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        string Echo(string text);
    }
    public class Service : ITest
    {
        public string Echo(string text)
        {
            return text;
        }
    }
    public static void Main()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
        host.Open();
        Console.WriteLine("Host opened");

        string data = @"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
                            <s:Header/>
                            <s:Body>
                                <Echo xmlns=""http://tempuri.org/"">
                                    <text>Hello</text>
                                </Echo>
                            </s:Body>
                        </s:Envelope>";
        var client = new WebClient();
        client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted);
        client.Headers[HttpRequestHeader.ContentType] = "text/xml; charset=utf-8";
        client.Headers.Add("SOAPAction", "http://tempuri.org/ITest/Echo");

        ManualResetEvent evt = new ManualResetEvent(false);
        client.UploadStringAsync(new Uri(baseAddress), "POST", data, evt);
        evt.WaitOne();
    }

    static void client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
    {
        Console.WriteLine(e.Result);
        ((ManualResetEvent)e.UserState).Set();
    }
}

他のヒント

Rather than trying to get the Async method to work, you could try using the non-async method but make it work asynchronously using the Task Parallel Library:

var client = new WebClient();
var data = File.ReadAllText("request.xml");
client.Headers.Add("Content-Type", "text/xml;charset=utf-8");
client.Headers.Add("SOAPAction", "some string");

Task.Factory.StartNew(() =>
{
    string returnVal = client.UploadString(new Uri("http://differentdomain/wcf/Service.svc"), data);
    Console.WriteLine(returnVal);
});

This is an overall better strategy, as it will work for all long-running operations and not just those which have an Async method and event handlers.

It should also make any communication/transport errors which occur easier to catch.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top