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#多线程和池_C#_Multithreading_Concurrency - Fatal编程技术网

C#多线程和池

C#多线程和池,c#,multithreading,concurrency,C#,Multithreading,Concurrency,各位开发者好 我有一个关于在.NET(Framework 4.0)Windows服务上实现多线程的问题 基本上,服务应该执行以下操作: 扫描文件系统(特定目录)以查看是否有要处理的文件 如果有需要处理的文件,它应该使用线程池机制来发出预定数量的线程 每个线程将执行单个文件的上载操作 一个线程完成后,将再次扫描文件系统,以查看是否还有其他文件要处理(我希望避免让两个线程对同一个文件执行操作) 我正在努力寻找一种方法,让我只做最后一步 现在,我有一个函数,用于检索在主线程中运行的最大并发线程数:

各位开发者好

我有一个关于在.NET(Framework 4.0)Windows服务上实现多线程的问题

基本上,服务应该执行以下操作:

  • 扫描文件系统(特定目录)以查看是否有要处理的文件
  • 如果有需要处理的文件,它应该使用线程池机制来发出预定数量的线程
  • 每个线程将执行单个文件的上载操作
  • 一个线程完成后,将再次扫描文件系统,以查看是否还有其他文件要处理(我希望避免让两个线程对同一个文件执行操作)
我正在努力寻找一种方法,让我只做最后一步

现在,我有一个函数,用于检索在主线程中运行的最大并发线程数:

int maximumNumberOfConcurrentThreads = getMaxThreads(databaseConnection);
然后,仍然在主线程中,我有一个函数扫描目录并返回一个包含要处理的文件的列表

List<FileToUploadInfo> filesToUpload = getFilesToUploadFromFS(directory);
每个线程都应该调用以下函数(返回void):

现在,按照程序的结构,如果最大线程数设置为5,我将从列表中获取5个元素并上传它们。 一旦所有5个都完成了,我再抓取5个,然后做同样的事情,直到我没有任何剩余,如下面的代码所示

for (int index = 0; index < filesToUpload.Count; index = index + maximumNumberOfConcurrentThreads) {
                try {
                    Parallel.For(0, maximumNumberOfConcurrentThreads, iteration => { if (index + iteration < filesToUpload .Count) { uploadFile(filesToUpload [index + iteration], databaseConnection, iteration); } });
                } 
                catch (System.ArgumentOutOfRangeException outOfRange) {
                    debug("Exception in Parallel.For [" + outOfRange.Message + "]"); 
                }
for(int index=0;index{if(index+iteration
但是,如果4个文件较小,每个文件的上载时间为5秒,而剩余的一个文件较大,需要30分钟,那么在4个文件上载后,我将只有一个文件上载,我需要等待它完成,然后才能开始上载列表中的其他文件

上传完列表中的所有文件后,我的服务进入睡眠状态,然后,当它再次醒来时,它再次扫描文件系统


什么策略最适合我的需要?走这条路线是明智的还是会造成并发性噩梦?我需要避免两次上载任何文件。

首先,如果您实际上没有使用
System.Thread
s的功能,那么您可能想切换到
System.Task
s。其次,如果4个小文件和1个大文件是常见的,那么这种策略并不可取(这里还有一个使用
Task
s的原因;当您使用线程时,所有完成的“工作线程”很可能会被阻塞,直到组中最慢的线程完成,所以您有5个线程占用资源,但只有一个线程在工作)。第三,您可能希望重新创建设计,使其具有(例如,只是一个变体)N+1个工作循环,其中N个循环通过链“从列表获取文件=>处理它=>获取下一个文件…”一个是通过搜索磁盘上的差异来更新列表。是的,您需要在单例列表周围实现一些简单的同步,但这并不太难,也不会影响性能(您提到有一些数据库要连接,因此与网络通信时间相比,即使数百万次同步操作也可能毫无意义).哦,我的错,我看到你在使用TPL的
并行。对于
,你已经在使用
任务
s。那么,我的评论的第二部分是正确的-尝试一些worker循环,也许它可以更快。另外,请注意,
并行。对于
并不能保证它会并行启动所有东西(这实际上很好,但无论如何,我想我应该提到它)。为了更好地确认它,可以将其他选项作为参数传递给它并进行设置(我不建议这样做)。这里有一个链接,显示在您尝试完成的相同过程中,我希望这会有所帮助。
uploadFile(fileToUpload, databaseConnection, currentThread);
for (int index = 0; index < filesToUpload.Count; index = index + maximumNumberOfConcurrentThreads) {
                try {
                    Parallel.For(0, maximumNumberOfConcurrentThreads, iteration => { if (index + iteration < filesToUpload .Count) { uploadFile(filesToUpload [index + iteration], databaseConnection, iteration); } });
                } 
                catch (System.ArgumentOutOfRangeException outOfRange) {
                    debug("Exception in Parallel.For [" + outOfRange.Message + "]"); 
                }