Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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
vs2008 c#:线程池问题_C#_Multithreading_Threadpool - Fatal编程技术网

vs2008 c#:线程池问题

vs2008 c#:线程池问题,c#,multithreading,threadpool,C#,Multithreading,Threadpool,我使用以下两种方法。名为DoMyWork1的方法可以很好地扩展,就像在3个线程中运行其中三个线程需要6秒钟一样。而DoMyJob方法根本不可伸缩。如果一个线程需要4秒,那么运行3个线程需要13秒。我做错了什么?除了线程池,文件读取和/或写入是否需要特殊的线程处理 我的电话号码 public static void Process(MyDelegate md , int threads) { int threadcount = threads; ManualResetEvent[

我使用以下两种方法。名为DoMyWork1的方法可以很好地扩展,就像在3个线程中运行其中三个线程需要6秒钟一样。而DoMyJob方法根本不可伸缩。如果一个线程需要4秒,那么运行3个线程需要13秒。我做错了什么?除了线程池,文件读取和/或写入是否需要特殊的线程处理

我的电话号码

public static void Process(MyDelegate md , int threads)
{
    int threadcount = threads;

    ManualResetEvent[] doneEvents = new ManualResetEvent[threadcount];

    DateTime dtstart = DateTime.Now;

    List<string> myfiles = GetMyFiles(@"c:\");


    for (int i = 0; i < threadcount; i++)
    {

        doneEvents[i] = new ManualResetEvent(false);
        MyState ms = new MyState();
        ms.ThreadIndex = i;
        ms.EventDone = doneEvents[i];
        ms.files = myfiles;
        ThreadPool.QueueUserWorkItem(md.Invoke, ms);
    }


    WaitHandle.WaitAll(doneEvents);

    DateTime dtend = DateTime.Now;
    TimeSpan ts = dtend - dtstart;
    Console.WriteLine("All complete in {0} seconds.", ts.ToString());
    Console.ReadLine();

}

public static void DoMyWork1(Object threadContext)
{
    MyState st = (MyState)threadContext;
    Console.WriteLine("thread {0} started...", st.ThreadIndex);

    Thread.Sleep(5000);

    Console.WriteLine("thread {0} finished...", st.ThreadIndex);
    st.EventDone.Set();
}



private static void DoMyJob(MyState st)
{
    Console.WriteLine("I am in thread {0} started...", st.ThreadIndex);


    string[] mystrings = new string[] { "one", "two", "three" };

    foreach (string s in mystrings)
    {
        foreach (string file in st.files)
        {
            if (!(new StreamReader(file).ReadToEnd().Contains(s)))
            {
                AppendToFile(String.Format("{0} word searching in file {1} in thread {2}", s, file, st.ThreadIndex));
            }


        }
    }

    Console.WriteLine("I am in thread {0} ended...", st.ThreadIndex);
}
publicstaticvoid进程(MyDelegate-md,int-threads)
{
int threadcount=线程数;
ManualResetEvent[]DoneeEvents=新的ManualResetEvent[threadcount];
DateTime dtstart=DateTime.Now;
List myfiles=GetMyFiles(@“c:\”);
对于(int i=0;i
在操作系统层,所有文件访问都将变成串行访问,因此线程化将产生与您所看到的完全相同的结果。

我有点惊讶-我希望第一次访问这些文件时缓存,然后剩余的访问只会命中内存。所以三个线程不应该比一个线程慢太多。如果您正在写入每个文件,这将产生不同的效果-AppendToFile函数到底做什么?

一个问题可能是您正在打开和读取每个文件,以及正在查找的每个新字符串

如果切换foreach循环的顺序并仅根据需要附加到文件中,会发生什么情况

我想你会看到更好的表现


理想情况下,如果您能够将文件读取全部从循环中取出,这将是最快的。I/O绑定操作总是会导致等待磁盘上的上下文开关返回数据。

只有当程序缺少CPU资源时,线程才能提高程序性能。您的程序并非如此,它应该可以在Taskmgr.exe的“性能”选项卡中随时看到。这里的慢资源是硬盘或网卡。ReadToEnd()调用非常慢,等待磁盘检索文件数据。您对文件数据所做的任何其他操作都很容易比这快3个数量级

线程将依次等待磁盘数据。事实上,线程很可能会使程序运行得慢很多。它们将导致磁盘驱动器头在磁盘上不相交的磁道之间来回跳转,因为每个线程使用的是不同的文件。真正缓慢的一件事是让头部寻找另一条轨迹。对于快速磁盘,通常约为10毫秒。相当于大约50万条CPU指令


除非有更快的磁盘,否则无法使程序运行得更快。固态硬盘很好。当心文件系统缓存的影响,当您第二次运行程序时,从缓存而不是磁盘检索文件数据时,它将运行得非常快。这在生产环境中很少发生。

您可以添加用于分派线程的代码吗?公共静态无效进程(MyDelegate md,int threads){int threadcount=threads;ManualResetEvent[]DoneeEvents=new ManualResetEvent[threadcount];DateTime dtstart=DateTime.Now;List myfiles=GetMyFiles(@“c:\”);for(int i=0;i