Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ActiveX对象和.NET垃圾收集器_C#_Multithreading - Fatal编程技术网

C# ActiveX对象和.NET垃圾收集器

C# ActiveX对象和.NET垃圾收集器,c#,multithreading,C#,Multithreading,我在.net中遇到了多线程问题。使用以下代码: class Program { private static ManualResetEvent[] resetEvents; private void cs(object o) { int xx = 0; while (true) { xx++; System.Xml.XmlDocument document = new Sys

我在.net中遇到了多线程问题。使用以下代码:

class Program
{
    private static ManualResetEvent[] resetEvents;

    private void cs(object o)
    {
        int xx = 0;
        while (true)
        {
            xx++;
            System.Xml.XmlDocument document = new System.Xml.XmlDocument();
            document.Load("ConsoleApplication6.exe.config");

            MSScriptControl.ScriptControlClass s = 
                newMSScriptControl.ScriptControlClass();
            s.Language = "JScript";
            object res = s.Eval("1+2");
            Console.WriteLine("thread {0} execution {1}" , o , xx);
            System.Threading.Thread.Sleep(5000);
        }

    }
    static void Main(string[] args)
    {
        Program c = new Program();
        for (int i = 0; i < 1000; i++)
        {
            System.Threading.Thread t = new System.Threading.Thread(
                new System.Threading.ParameterizedThreadStart(c.cs));
            t.Start((object)i);
        }
    }
}
类程序
{
专用静态手动重置事件[]重置事件;
私人文书主任(对象o)
{
int xx=0;
while(true)
{
xx++;
System.Xml.XmlDocument document=new System.Xml.XmlDocument();
Load(“ConsoleApplication6.exe.config”);
MSScriptControl.ScriptControlClass s=
newMSScriptControl.ScriptControlClass();
s、 Language=“JScript”;
对象res=s.Eval(“1+2”);
WriteLine(“线程{0}执行{1}”,o,xx);
系统线程线程睡眠(5000);
}
}
静态void Main(字符串[]参数)
{
程序c=新程序();
对于(int i=0;i<1000;i++)
{
System.Threading.Thread t=新的System.Threading.Thread(
新的System.Threading.ParameterizedThreadStart(c.cs));
t、 启动((对象)i);
}
}
}

执行此代码时,它会在几分钟后崩溃。为什么它会崩溃?如何防止崩溃?

您将启动1000个线程。这是1000 MB的堆栈空间加上线程创建的所有对象。我猜你的记忆快用完了。你想实现什么?

创建比处理器核心更多的线程几乎没有意义。b/c应用程序将花费大量时间切换上下文,并且你将看不到任何性能提升。同时运行的唯一线程数等于您的计算机拥有的内核数。为什么这必须用1000个线程来完成?(显然,我假设你没有1000核的机器)

鉴于提供的代码,这个应用程序的某些方面可能并不明显。也就是说,我无法重现崩溃,但我可以运行大量的内存使用量(29“xx++”s时为160MB)

我怀疑ScriptControlClass在内存中保持活动状态。虽然可能有更好的方法解决这个问题,但通过添加以下内容,我能够将内存保持在一致的60-70MB:

Console.WriteLine("thread {0} execution {1}" , o , xx);
s = null;

更新
我对这段代码在内存方面也有类似的结果,但是下面的代码稍微快一点。几分钟后,当
xx<30
更改回
true
时,内存使用量为一致的51MB

class Program
{
    private static ManualResetEvent[] resetEvents;

    [ThreadStatic]
    static ScriptControlClass s;

    private void cs(object o)
    {
        int xx = 0;

        if (s == null)
        {
            s = new ScriptControlClass();
        }

        /* you should be able to see consistent memory usage after 30 iterations */
        while (xx < 30)
        {
            xx++;

            //Unsure why this is here but doesn't seem to affect the memory usage
            //  like the ScriptControlClass object.
            System.Xml.XmlDocument document = new System.Xml.XmlDocument();
            document.Load("ConsoleApplication6.exe.config");

            s.Language = "JScript";
            object res = s.Eval("1+2");
            Console.WriteLine("thread {0} execution {1}", o, xx);

            System.Threading.Thread.Sleep(5000);
        }

        s = null;

    }
    static void Main(string[] args)
    {
        Program c = new Program();
        for (int i = 0; i < 1000; i++)
        {
            System.Threading.Thread t = new System.Threading.Thread(
                new System.Threading.ParameterizedThreadStart(c.cs));
            t.Start((object)i);
        }
    }
}
类程序
{
专用静态手动重置事件[]重置事件;
[线程静态]
静态脚本控件类;
私人文书主任(对象o)
{
int xx=0;
如果(s==null)
{
s=新的ScriptControlClass();
}
/*您应该能够在30次迭代后看到一致的内存使用情况*/
而(xx<30)
{
xx++;
//不确定为什么会出现这种情况,但似乎不会影响内存使用
//就像ScriptControlClass对象一样。
System.Xml.XmlDocument document=new System.Xml.XmlDocument();
Load(“ConsoleApplication6.exe.config”);
s、 Language=“JScript”;
对象res=s.Eval(“1+2”);
WriteLine(“线程{0}执行{1}”,o,xx);
系统线程线程睡眠(5000);
}
s=零;
}
静态void Main(字符串[]参数)
{
程序c=新程序();
对于(int i=0;i<1000;i++)
{
System.Threading.Thread t=新的System.Threading.Thread(
新的System.Threading.ParameterizedThreadStart(c.cs));
t、 启动((对象)i);
}
}
}

更新2

我在谷歌上找不到任何关于在多线程环境中使用ScriptControlClass的信息

@Brian:哇。他实际上用简单的方法创建了StackOverFlow:)@Joel:我怀疑OP是否得到了StackOverflowException,因为代码没有耗尽堆栈。可能是OutOfMemoryException。如何计算堆栈空间中的1000MB?我计数(4(
o
)+4(
xx
)+4(
document
)+4(
s
)+4(
res
)+4(返回地址))*1000字节=6KB。@Konrad:每个线程在.NET中每个默认值都有1MB的堆栈(除非是ASP应用程序,在这种情况下,默认值是256KB)。代码会创建1000个线程,因此进程会为1000 MB的堆栈保留空间。@Konrad,这是因为默认情况下每个线程都有1 MB的堆栈,并且有1000个堆栈。