Ошибка «WebException» на кнопке «Назад» даже при вызове асинхронного метода «void» - PullRequest
4 голосов
/ 01 апреля 2012

У меня есть приложение для Windows Phone, которое позволяет пользователю взаимодействовать с ним. Каждое взаимодействие всегда приводит к асинхронному вызову WCF.
Кроме того, некоторые взаимодействия приведут к открытию браузера, карт, электронной почты и т. Д. *

Проблема в том, что когда я нажимаю кнопку "Назад", я иногда получаю следующую ошибку
"An error (WebException) occurred while transmitting data over the HTTP channel."

со следующей трассировкой стека:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason) at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result) at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(IAsyncResult result) at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2) at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadPool.WorkItem.doWork(Object o) at System.Threading.Timer.ring()

Насколько я понимаю, это происходит потому, что мое приложение открыло другое приложение (браузер, карты и т. Д.) До того, как оно успело выполнить EndMyAsyncMethod(System.IAsyncResult result). Достаточно справедливо ...

Что действительно раздражает, так это то, что кажется, что это нужно исправить путем клонирования метода на стороне сервера, только сделав его void со следующим контрактом операции [OperationContract(IsOneWay = true)], но я все еще получаю ошибку.

Хуже всего то, что исключение выдается в сгенерированной системой части кода и, следовательно, не может быть перехвачено вручную, вызывая просто сбой приложения.

Я просто не понимаю необходимости выполнения метода Endxxx, когда он явно помечен как OneWay и void.


EDIT

Я нашел похожую проблему здесь . Кажется, что это связано с получением сообщения в службу (а не с обратным вызовом клиента). Мой следующий вопрос:
если я сейчас вызываю метод, помеченный AsyncPattern и OneWay, что именно мне следует ожидать на клиенте, чтобы убедиться, что сообщение было успешно передано?

Это новое определение сервиса:

[OperationContract(IsOneWay = true, AsyncPattern = true)]
IAsyncResult BeginCacheQueryWithoutCallback(string param1, QueryInfoDataContract queryInfo, AsyncCallback cb, Object s);

void EndCacheQueryWithoutCallback(IAsyncResult r);

И реализация:

public IAsyncResult BeginCacheQueryWithoutCallback(string param1, QueryInfoDataContract queryInfo, AsyncCallback cb, Object s)
{
        // do some stuff
        return new CompletedAsyncResult<string>("");
}
public void EndCacheQueryWithoutCallback(IAsyncResult r)
{
}

1 Ответ

0 голосов
/ 13 мая 2012

Единственной гарантией того, что сообщение было доставлено для односторонней привязки, является включение надежного обмена сообщениями и отсутствие ошибок связи (неправильный адрес, привязка и т. Д.).список привязок, поддерживающих надежный обмен сообщениями:

basicHttpBinding   - RM not supported

wsHttpBinding      - RM supported, not default

wsDualHttpBinding  - RM implicit

netTcpBinding      - RM supported, not default

Например, для tcpBinding:

<binding>
    <netTcpBinding>
        <binding name="MyTcpBinding">
            <reliableSession enabled="true" />
        </binding>
    </netTcpBinding>
</binding>

Или:

<customHttpBinding>
   <binding configurationName="customReliableBinding">
      <reliableSession ordered="true" />
   </binding>
</customBinding>
...