开发者

OutOfMemoryException using timer elapsed event c#

开发者 https://www.devze.com 2023-02-22 11:24 出处:网络
I am getting an out of memory exception when using a time. Could it have something to do with using the timer in a struct - Is it possible to have a timer in a struct such as below:

I am getting an out of memory exception when using a time. Could it have something to do with using the timer in a struct - Is it possible to have a timer in a struct such as below:

 public struct SessionStruct 
{
    private bool _isElapsed;
    public bool isElapsed
    {
        get{return _isElapsed;}
        set { _isElapsed = value; }
    }
    public string sessionID
    {
        get;
        set;
    }
    public DateTime time
    {
        get;
        set;
    }

    public Timer timer
    { get; set; }

};

This is the elapsed event handler:

static void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        req = "<Request><ID>1234567</ID><type>10</type><attribute>" + session1.sessionID + "|</attribute></Request>";}

[EDIT]

Here is the code for the instantiating and setting values - this is only part of it...

        public Request(string request, Database db)
    {

//instantation s = new SessionStruct(); s.timer = new Timer(60000); s.timer.Enabled = true; //db = new Database(); try { Debug.WriteLine("Started a new request"); doc = new XmlDocument(); doc.LoadXml(request); string attribute = ""; //string sessionID = ""; ArrayList attributeArray = new ArrayList(); ArrayList queryArray = new ArrayList();

            int iteration = 0;

            bool hasSpecial = false ;
        nodelist = doc.SelectNodes("/Request");
        foreach (XmlNode xn in nodelist)
        {
            try
            {
                type = xn["type"].InnerText;
                id = xn["ID"].InnerText;
                attribute = xn["attribute"].InnerText;
                Debug.WriteLine("Processing Request of type: " + type + "\nWith Id number: " + id + "\nWith attribute string: " + attribute);
                for (int i = attribute.IndexOf('|'); i != -1; )
                {
                    attributeArray.Add(attribute.Substring(0, i));
                    if (attribute.Substring(0, i).Contains('\''))
                        hasSpecial = true;
                    attribute = attribute.Substring(i + 1);

                    i = attribute.IndexOf('|');
                }

//setting variables if (type == "1" && attributeArray.Count != 2) { s.sessionID = attributeArray[0].ToString(); s.time = DateTime.Now; s.timer.Start(); isNotLogin = true; attributeArray.RemoveAt(0); } 开发者_Go百科 else if (type != "1") { s.sessionID = attributeArray[0].ToString(); s.time = DateTime.Now; s.timer.Start(); isNotLogin = true; attributeArray.RemoveAt(0); }

I return the struct here

 public SessionStruct getSessionStruct()
    {
            return s; 
    }

It is returned to another class like:

                        sessStruct2 = iRequest.getSessionStruct();
                        int x;
                        for(x = 0; x< session.Count; x++)
                        {
                            sessStruct = (SessionStruct)session[x];


                            if (sessStruct.sessionID == sessStruct2.sessionID)
                            {
                                Debug.WriteLine("Resetting Session Timer");
                                session.RemoveAt(x);
                                sessStruct2.timer.Stop(); //resetting timer
                                sessStruct2.timer.Start();
                                Debug.WriteLine("Session Timer Reset SUCCESSFUL");
                                session.Add((object)sessStruct2);
                                Debug.WriteLine("Added Session        "+sessStruct2.sessionID+" Successfully to sessions table");
                                guiServer.log("Added Session " + sessStruct2.sessionID + " Successfully to sessions table");
                                break;
                            }

                       }

                        if(x==session.Count)
                        {
                                session.Add(iRequest.getSessionStruct());
                                Debug.WriteLine("Added the session");
                        }

And I created a thread that checks to see whether the timer is elapsed like this

while (true)
            {
                if (session.Count > 0)
                {

                    session1 = (SessionStruct)session[0];
                    session1.timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed)

                }
            }

And here is the stack trace:

 first chance exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll

System.Transactions Critical: 0 : http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/UnhandledUnhandled exceptionVNurseService.exeSystem.OutOfMemoryException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089Exception of type 'System.OutOfMemoryException' was thrown. at System.MulticastDelegate.CombineImpl(Delegate follow) at System.Timers.Timer.add_Elapsed(ElapsedEventHandler value) at VNurseService.Server.Session.checkSessionList() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. at System.MulticastDelegate.CombineImpl(Delegate follow) at System.Timers.Timer.add_Elapsed(ElapsedEventHandler value) at VNurseService.Server.Session.checkSessionList() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() An unhandled exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll

I know this is confusing but we are creating psuedo sessions and the session id comes from a request and when the request is parsed it inserts the session id and the time and then starts the timer into a struct. The struct is then returned to the "main" class and then it is checked against other sessions in the session arraylist. If it is in the arraylist it removes the current and adds the new struct at the end of the arraylist. And then the new thread checks the arraylist to see if the session at index 0 of the arraylist has elapsed.

I hope this makes sense. If there is another implementation or way of doing it please let me know.

Thanks.


Yes, you can have a Timer (or any other type) be a member of a struct. Incidentally, you should strongly consider either changing this to be a class (is there any particular reason you made it a struct?) or removing the setters from your properties; mutable structs, as you have here, are generally regarded as Pure Evil.

There's not much here that actually tells anything about your environment and what might be causing you to run out of memory. Can you shed some more light on how you're actually using the struct?

Edit After Question Edit

You should not be attaching to the timer's event repeatedly as you are. Your while loop will continue to attach copies of the timer's handler, and this is likely where you're running out of memory.

0

精彩评论

暂无评论...
验证码 换一张
取 消