Monotouch и WCF, использование памяти - PullRequest
1 голос
/ 03 февраля 2012

У меня есть сервис WCF, размещенный на веб-сайте, и приложение Monotouch, которое может отображать и обновлять PDF-документы из сервиса. Размер PDF файлов может быть от 1 байта до 20 Мб. Когда у меня мало документов (меньше 100, а общий размер документов - 30 МБ), процесс обновления успешно завершается. Но когда у меня много документов (более 300, а общий размер документов составляет 100 МБ), моя программа завершает работу на iPad 1, но на iPad 2 все еще работает.

Мне кажется, проблема в использовании памяти . iOS убивает мое приложение, когда оно использует много памяти. Но я не знаю, где проблема, может быть, Monotouch GC не очищает память от байтовых массивов fileData?

Способ обновления документов на iPad:

protected bool BeginUpdateProcess()
{
  try {
    var binding = new BasicHttpBinding();
    binding.MaxBufferSize = 52428800;
    binding.MaxBufferPoolSize = binding.MaxReceivedMessageSize = 52428800L;
    binding.ReaderQuotas.MaxStringContentLength = binding.ReaderQuotas.MaxArrayLength = 52428800;
    var endpoint = new EndpointAddress(string.Format("http://{0}/Services/UpdateDataService.svc", UpdateInfo.Instance.ServerIP));
    using (var dataService = new UpdateDataServiceClient(binding, endpoint)) {
        // Get document list for update
        int[] docIds;
        try {
            docIds = dataService.GetModifiedDocumentIds(mLastUpdated);
        } catch (Exception ex) {
            LogWriter.Instance.WriteToLog("UpdateFromServiceEror: Can't load modified document ids list", ex);
            return false;
        }

        // Get each document content and save it to iPad
        for (int i = 0; i < docIds.Length; i++) {
            if (Canceled) {
                return true;
            }
            try {
                byte[] fileData = dataService.GetDocumentTransData(docIds[i]);
                SaveDocument(fileData);
            } catch (Exception ex) {
                LogWriter.Instance.WriteToLog(string.Format("Can't load or save file, id={0}", docIds[i]), ex);
                return false;
            }
        }
        dataService.Close();
    }
} catch (Exception ex) {
    LogWriter.Instance.WriteToLog("Error when update from service", ex);
}
 }

Настройки WCF на сайте:

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<behaviors>
    <serviceBehaviors>
        <behavior name="Default">
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
    </serviceBehaviors>
</behaviors>

<bindings>
    <basicHttpBinding>
        <binding name="Transport"
            closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="52428800" maxBufferPoolSize="524288" maxReceivedMessageSize="52428800"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
            <readerQuotas maxDepth="64"
                        maxStringContentLength="52428800"
                        maxArrayLength="52428800"
                        maxBytesPerRead="16384"
                        maxNameTableCharCount="16384" />
        </binding>
    </basicHttpBinding>
</bindings>

<services>
    <service name="iDict.Site.Services.UpdateDataService" behaviorConfiguration="Default">
        <host>
            <baseAddresses>
                <add baseAddress="http://localhost:57709/Services/UpdateDataService.svc"/>
            </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="Transport" contract="iDict.Site.Services.IUpdateDataService" />
    </service>
</services>

1 Ответ

1 голос
/ 04 февраля 2012

Вот несколько вещей, которые могут вам помочь:

  • 52428800 - большой буфер для устройств;

  • Передаются ли документы PDF вXML?Если это так, в какой-то момент вы получите PDF-документ в формате string (не очень эффективный, с точки зрения памяти) и byte[] fileData.Это может касаться доступной оперативной памяти iPad первого поколения.Возможным способом избежать этой ситуации является наличие веб-службы, которая возвращает URL-адреса файлов.После этого каждый URL может быть легко Stream 'переименован с веб-сервера в локальный файл без использования большого объема памяти;

  • у iPad2 больше ОЗУ, с ним может работать вышеуказанное, но этов конечном итоге не для больших документов.В то же время использование Stream приведет к ограничению пространства хранения устройств;

  • В зависимости от используемой версии MonoTouch, может попасть ошибка # 386 .Если вы можете, я предлагаю вам попробовать последнюю версию MonoTouch (бета-версию на данный момент), которая решает эти проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...