c#简单等待线程队列(队列已满时等待)从Sharepoint下载多个文件

c#简单等待线程队列(队列已满时等待)从Sharepoint下载多个文件,c#,multithreading,sharepoint,queue,download,C#,Multithreading,Sharepoint,Queue,Download,我编写了一个简单的程序,使用线程技术从Sharepoint同时下载多个文件。我使用了一个Do-While循环来确保每当队列满时程序都会等待 请看我下面的代码注释。我正在寻找一种更有效的方法,让程序在队列已满时等待。使用Do-While循环,通过添加Thread.Sleep(1000),我的程序有70%的cpu使用率,它将减少到30%的cpu使用率,但我认为必须有一种更有效的方法,同时不影响队列的性能?谢谢 // Main Program to dispatch Threads to downlo

我编写了一个简单的程序,使用线程技术从Sharepoint同时下载多个文件。我使用了一个Do-While循环来确保每当队列满时程序都会等待

请看我下面的代码注释。我正在寻找一种更有效的方法,让程序在队列已满时等待。使用Do-While循环,通过添加Thread.Sleep(1000),我的程序有70%的cpu使用率,它将减少到30%的cpu使用率,但我认为必须有一种更有效的方法,同时不影响队列的性能?谢谢

// Main Program to dispatch Threads to download files from Sharepoint
bool addedtoDownloader;
                    do
                    {
                        addedtoDownloader = ThreadDownloader.addJob(conn, item.FileRef, LocalFolderPath);

                       // ===== by having the following 2 lines below reduce CPU usage
                            if (addedtoDownloader == false)
                            System.Threading.Thread.Sleep(1000);
                       // ====== Is there a better way to do this? ================
                    }
                    while (addedtoDownloader == false);





class ThreadDownloader
{
    public const int MaxThread = 15;

    public static List<Thread> ThreadList = new List<Thread>();


    public static bool addJob(ClientContext conn, string SrcFileURL, string DestFolder)
    {
        RefreshThreadList();

        if (ThreadList.Count() < MaxThread)
        {

            Thread t = new Thread(() => Program.DownloadFile(conn, SrcFileURL, DestFolder));
            ThreadList.Add(t);
            t.Start();
            return true;
        }

        return false;


    }

    public static void RefreshThreadList()
    {
        List<Thread> aliveThreadList = new List<Thread>();

        foreach (var t in ThreadList)
        {
            if (t.IsAlive)
            {
                aliveThreadList.Add(t);
            }
        }

        ThreadList.Clear();
        ThreadList = aliveThreadList;
    }



}
//分配线程从Sharepoint下载文件的主程序
布尔加法器;
做
{
addedtoDownloader=ThreadDownloader.addJob(conn,item.FileRef,LocalFolderPath);
//======通过以下两行减少CPU使用
如果(addedtoDownloader==false)
系统线程线程睡眠(1000);
//======有更好的方法吗================
}
while(addedtoDownloader==false);
类线程下载器
{
public const int MaxThread=15;
public static List ThreadList=new List();
公共静态bool addJob(ClientContext conn、string SrcFileURL、string DestFolder)
{
刷新线程列表();
if(ThreadList.Count()Program.DownloadFile(conn,SrcFileURL,DestFolder));
添加(t);
t、 Start();
返回true;
}
返回false;
}
公共静态无效刷新线程列表()
{
List aliveThreadList=新列表();
foreach(线程列表中的变量t)
{
如果(t.IsAlive)
{
aliveThreadList.Add(t);
}
}
ThreadList.Clear();
ThreadList=aliveThreadList;
}
}

这似乎是信号量的一个很好的使用案例:

private static SemaphoreSlim semaphore = new SemaphoreSlim(MaxThread);

public static void addJob(ClientContext conn, string SrcFileURL, string DestFolder)
{
    semaphore.Wait();

    RefreshThreadList();

    Thread t = new Thread(() =>
        {
            try
            {
                Program.DownloadFile(conn, SrcFileURL, DestFolder);
            }
            finally
            {
                semaphore.Release();
            }
        });
    ThreadList.Add(t);
    t.Start();
}

使用a-顾名思义,它是为这类事情设计的。谢谢Pragmateek,但是如果我只使用.net 3.5呢?而且,在这种情况下,我认为我们不再需要ThreadList了,对吧?如果你坚持使用3.5,只需使用好的旧信号量类。是的,我认为你可以摆脱线程列表谢谢它起作用了!我对信号量的内部工作不太了解,您认为这种方法比我在问题中使用的do-While循环好吗?我的版本是线程安全的吗?我知道有很多问题,但是谢谢!使用像信号量这样的同步原语更好,通常应该避免“忙等待”(即循环直到条件为真)。