Monotouch和WCF,内存使用情况

时间:2012-02-03 17:01:24

标签: .net wcf ipad memory-management xamarin.ios

我在网站和Monotouch应用程序中托管了WCF服务,可以显示和更新服务中的PDF文档。 PDF文件大小可以从1字节到20 Mb。 如果文档很少(少于100个,文档总大小为30Mb),则更新过程会成功完成。但是,当我有很多文档(超过300个,常见文档大小为100Mb)时,我的程序终止于iPad 1,但在iPad 2上仍然有效。

我认为内存使用中的问题。当iOS使用许多内存时,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 个答案:

答案 0 :(得分:1)

以下是一些可能对您有所帮助的事情:

  • 52428800是设备的重要缓冲区;

  • PDF文档是否以XML格式传输?如果是这样,您将在某个时刻将您的PDF文档同时放在string(不是非常有效,内存方面)和byte[] fileData。这可能会超过第一代iPad的可用内存。避免这种情况的一种可能方法是使Web服务返回文件的URL。然后,每个URL都可以轻松Stream从Web服务器到本地文件,而无需占用太多​​内存;

  • iPad2上面可能有更多的RAM可用,但这对于较大的文档最终会失败。同时使用Stream会限制您使用设备的存储空间;

  • 根据您使用的MonoTouch版本,可能正在点击bug #386。如果可以,我建议您尝试最新的MonoTouch版本(目前是测试版),以解决这些问题。