在c#中发布httpwebrequest会占用大量内存

时间:2013-11-01 15:16:57

标签: c# httpwebrequest google-cloud-messaging

我使用以下gcm类发布数据,向大约10,000个Android设备发送gcm通知:

class GCMandroid
{
    private JArray RegIDs;
    private string tickerText;
    private string level;
    private string id;
    private string title;
    private string message;
    private string date;

    public GCMandroid(List<string> Ids,string tickerText,string level,string id,
        string title,string message,string date)
    {
        this.RegIDs = new JArray(Ids.ToArray());
        this.tickerText = tickerText;
        this.level = level;
        this.id = id;
        this.date = date;
        this.title = title;
        this.message = message;
    }
    public string GetPostData()
    {
        string postData =
            "{ \"registration_ids\": " + this.RegIDs + ", " +
            "\"time_to_live\":" + "43200" + ", " +
            "\"collapse_key\":\"" + "Key" + "\", " +
            "\"data\": {\"tickerText\":\"" + this.tickerText + "\", " +
            "\"level\":\"" + this.level + "\", " +
            "\"id\":\"" + this.id + "\", " +
            "\"date\":\"" + this.date + "\", " +
            "\"title\":\"" + this.title + "\", " +
            "\"message\": \"" + this.message + "\"}}";
        return postData;
    }
    public bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        return true;
    }

    public string SendGCMNotification(string apiKey, string postData, string postDataContentType = "application/json")
    {
        ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);

        //
        // MESSAGE CONTENT
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);

        //
        // CREATE REQUEST
        HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
        Request.Method = "POST";
        Request.KeepAlive = false;
        Request.ContentType = postDataContentType;
        Request.Headers.Add(string.Format("Authorization: key={0}", apiKey));
        Request.ContentLength = byteArray.Length;

        Stream dataStream = Request.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();

        //
        // SEND MESSAGE
        try
        {
            WebResponse Response = Request.GetResponse();
            HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;
            if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
            {
                var text = "Unauthorized - need new token";
            }
            else if (!ResponseCode.Equals(HttpStatusCode.OK))
            {
                var text = "Response from web service isn't OK";
            }

            StreamReader Reader = new StreamReader(Response.GetResponseStream());
            string responseLine = Reader.ReadToEnd();
            Reader.Close();
            Response.Close();
            return responseLine;
        }
        catch (Exception e)
        {
        }
        return "error";
    }
}

这在包含计时器的Windows窗体中使用,如果不忙于从数据库中获取数据并将其发送到大约10,000个Android设备并且调用时,每10秒将勾选一个后台工作者:

GCMandroid gcm = new GCMandroid(sublist, tickerText, level, id, title, message,date);
gcm.SendGCMNotification(AndroidApiKey, gcm.GetPostData());

其中sublist最多为1000,因为每个请求的gcm云配额。通知很快收到,但程序使用了大量内存。

在尝试检测导致ram使用的项目主要部分(4天内进程使用的2 GB内存)时删除函数后,我发现发送通知导致此ram使用。

我用httpwebrequset搜索了ram使用的问题,但没有发现任何相关内容。我也尝试调用垃圾收集器,但它并没有清除大部分内存使用的所有内存;它只清除了所用RAM总内存的5%左右。任何人都可以帮助阻止这种大量内存使用。

1 个答案:

答案 0 :(得分:0)

你的GetPostData函数附加了大量的字符串。请改用StringBuilder。