OutOfMemoryException 使用计时器经过事件 C#

发布于 2024-10-30 17:14:26 字数 6531 浏览 0 评论 0原文

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

 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)
    {

//实例 s = new SessionStruct(); s.timer = 新计时器(60000); s.timer.Enabled = true; //db = 新数据库(); 尝试 { Debug.WriteLine("开始一个新请求"); doc = new XmlDocument(); doc.LoadXml(请求); 字符串属性=“”; //字符串会话ID = ""; ArrayList 属性Array = new ArrayList(); ArrayList 查询数组 = 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" && attributeArray.Count != 2) { s.sessionID = attributeArray[0].ToString(); s.time = DateTime.Now; s.timer.Start(); 未登录 = true; attributeArray.RemoveAt(0); } 否则如果(类型!=“1”) { s.sessionID = attributeArray[0].ToString(); s.time = DateTime.Now; s.timer.Start(); 未登录 = 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 异常VNurseService.exeSystem.OutOfMemoryException,mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089Exception 类型为“System.OutOfMemoryException”。在 System.MulticastDelegate.CombineImpl(委托跟随) 在 System.Timers.Timer.add_Elapsed(ElapsedEventHandler 值) 在 VNurseService.Server.Session.checkSessionList() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback回调,对象状态,布尔ignoreSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,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(对象状态) 在System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback回调,对象状态,布尔ignoreSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback 回调,对象状态) 在 System.Threading.ThreadHelper.ThreadStart() mscorlib.dll 中发生了类型为“System.OutOfMemoryException”的未处理异常

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

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

谢谢。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枕梦 2024-11-06 17:14:26

是的,您可以让 Timer(或任何其他类型)成为 struct 的成员。顺便说一句,您应该强烈考虑将其更改为(是否有任何特殊原因将其设为结构?)或删除来自您的财产的设置者;正如这里所示,可变结构通常被视为纯粹的邪恶。

这里没有太多内容实际上可以告诉您有关您的环境以及可能导致您内存不足的任何信息。您能否进一步说明一下您实际上是如何使用struct的?

在问题编辑后编辑

您不应该像现在这样重复附加到计时器的事件。您的 while 循环将继续附加计时器处理程序的副本,这可能会导致内存不足。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文