使用timer逝去事件c#的OutOfMemoryException

时间:2011-04-05 16:54:50

标签: c# struct out-of-memory

使用时间时出现内存不足异常。它可能与在结构中使用计时器有关 - 是否可以在结构中有一个计时器,如下所示:

 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; }

};

这是经过的事件处理程序:

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

[编辑]

以下是实例化和设置值的代码 - 这只是其中的一部分......

        public Request(string request, Database db)
    {

// instantation             s = new SessionStruct();             s.timer = new Timer(60000);             s.timer.Enabled = true;             // db = new Database();             尝试             {                 Debug.WriteLine(“已启动新请求”);                 doc = new XmlDocument();                 doc.LoadXml(请求);                 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('|');
                }

//设置变量                     if(type ==“1”&amp;&amp; attributeArray.Count!= 2)                     {                         s.sessionID = attributeArray [0] .ToString();                         s.time = DateTime.Now;                         s.timer.Start();                         isNotLogin = true;                         attributeArray.RemoveAt(0);                     }                     否则if(type!=“1”)                     {                         s.sessionID = attributeArray [0] .ToString();                         s.time = DateTime.Now;                         s.timer.Start();                         isNotLogin = true;                         attributeArray.RemoveAt(0);                     }

我在这里返回结构

 public SessionStruct getSessionStruct()
    {
            return s; 
    }

它返回到另一个类,如:

                        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");
                        }

我创建了一个线程来检查计时器是否已经过了这样的

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

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

                }
            }

这是堆栈跟踪:

 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 = b77a5c561934e089抛出了类型'System.OutOfMemoryException'的异常。在System.MulticastDelegate.CombineImpl(委托跟随)    在System.Timers.Timer.add_Elapsed(ElapsedEventHandler值)    在VNurseService.Server.Session.checkSessionList()    在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean ignoreSyncCtx)    在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)    在System.Threading.ThreadHelper.ThreadStart()System.OutOfMemoryException:抛出了类型'System.OutOfMemoryException'的异常。    在System.MulticastDelegate.CombineImpl(委托跟随)    在System.Timers.Timer.add_Elapsed(ElapsedEventHandler值)    在VNurseService.Server.Session.checkSessionList()    在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean ignoreSyncCtx)    在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)    在System.Threading.ThreadHelper.ThreadStart() mscorlib.dll中出现未处理的“System.OutOfMemoryException”类型异常

我知道这很令人困惑,但我们正在创建psuedo会话,会话ID来自请求,当解析请求时,它会插入会话ID和时间,然后将计时器启动到结构中。然后将结构返回到“main”类,然后检查会话arraylist中的其他会话。如果它在arraylist中,则删除当前并在arraylist的末尾添加新结构。然后新线程检查arraylist以查看arraylist的索引0处的会话是否已经过去。

我希望这是有道理的。如果有其他实施或方式,请告诉我。

感谢。

1 个答案:

答案 0 :(得分:3)

是的,您可以Timer(或任何其他类型)成为struct的成员。顺便说一下,你应强烈考虑将其更改为class(有什么特别的原因让你成为struct?)或从你的属性中删除setter;如你所见,可变结构通常被认为是纯粹邪恶。

这里没有太多关于你的环境以及可能导致你内存耗尽的事情。你能否详细了解一下你如何使用 struct

编辑问题后编辑

您不应该像现在一样反复附加计时器的事件。您的while循环将继续附加计时器处理程序的副本,这可能是您内存不足的地方。