0

I've implemented the following WCF service:

namespace TeaService
{
    public class TeaService : ITeaService
    {
        public string PrepareTea(string tea)
        {
            System.Threading.Thread.Sleep(61000);
            return "A nice cup of " + tea + " tea will be ready in a few minutes.";
        }
    }
}

The service uses the default basichttpbinding, and the binding configuration is configured like this:

<bindings>
  <basicHttpBinding>
    <binding openTimeout="00:05:00" receiveTimeout="00:05:00" sendTimeout="00:05:00" closeTimeout="00:05:00"></binding>
  </basicHttpBinding>
</bindings>

That is, all timeout values are set to five minutes.

A Windows Phone 8 client application invokes the service:

namespace TeaClient
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();

            var client = new TeaServiceClient();
            client.PrepareTeaCompleted += Client_PrepareTeaCompleted;
            client.PrepareTeaAsync("Rooibos");
        }

        private void Client_PrepareTeaCompleted(object sender, PrepareTeaCompletedEventArgs e)
        {
            tb.Text = e.Result;
        }
    }
}

The "tb" is a textbox defined in the xaml view.

In the ServicesReferences.ClientConfig, the timeout values for the basicHttpBinding are set like so:

<bindings>
    <basicHttpBinding>
        <binding name="BasicHttpBinding_ITeaService" maxBufferSize="2147483647"
            maxReceivedMessageSize="2147483647" openTimeout="00:05:00" receiveTimeout="00:05:00" sendTimeout="00:05:00" closeTimeout="00:05:00">
            <security mode="None" />
        </binding>
    </basicHttpBinding>
</bindings>

The problem: After one minute a CommunicationException is thrown client side.

$exception  {System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)
   --- End of inner exception stack trace ---
   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
   at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
   --- End of inner exception stack trace ---
   at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
   at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
   at TeaClient.TeaService.TeaServiceClient.TeaServiceClientChannel.EndPrepareTea(IAsyncResult result)
   at TeaClient.TeaService.TeaServiceClient.TeaClient.TeaService.ITeaService.EndPrepareTea(IAsyncResult result)
   at TeaClient.TeaService.TeaServiceClient.OnEndPrepareTea(IAsyncResult result)
   at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)}   System.Exception {System.ServiceModel.CommunicationException}

I can't figure out why this is. If I implement the exact same WCF client specific code in a WPF desktop application, no exception will be thrown. I can confirm that the service works fine, and the windows phone application works fine as well as long as I remove the Thread.Sleep(61000). In my "real-world" production scenario (which this simplified example reflects), the client has to be able to wait for longer than one minute without throwing a CommunicationException. Since the example works if I do the same thing from a WPF application, I'm suspecious that the problem relates to a limitation on the Windows Phone platform. But I can't find any information that states that WCF calls can't take any longer than one minute on Windows Phone.

Furthermore I've tried setting the OperationTimeout on the client proxy like so:

client.InnerChannel.OperationTimeout = TimeSpan.FromMinutes(5.0);

But with no luck. Any suggestions are welcome.

EDIT: The duplicate-question marked by nvoigt is related to the HttpClient. This question is about a WCF client proxy using the BasicHttpBinding. The underlying issue is without doubt the exact same, and therefore we've concluded that it's a platform limitation.

sje
  • 315
  • 2
  • 8
  • Could you make use of WebSockets instead? If you use NetHttpBinding and use a callback contract, you could send your request to the server, and then the server sends the response on the callback. If this is an option for you, I can provide more information. – MattC Oct 02 '15 at 18:47
  • Unfortunately no. BasicHttpBinding is the only supported wcf binding on Windows Phone 8.0... or? Maybe it could be done via a portable class library? Thanks for the suggestion. – sje Oct 05 '15 at 06:50

1 Answers1

0

Windows Phone apps don't have an app.config file so none of the timeouts specified will apply. Instead you need to set it on the client instance like this:

var client = new TeaServiceClient();
client.ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan.FromMinutes(5);
MattC
  • 373
  • 1
  • 6
  • That is correct (that no app.config exists), but the ServiceReferences.ClientConfig does, and the timeout values set from there does apply to the client proxy as they should. So the timeout values has been set correctly on the client. If I inspect the client.ChannelFactory.Endpoint.Binding.SendTimeout I see the value that I specified in ServiceReferences.ClientConfig. – sje Oct 02 '15 at 06:32