【发布时间】:2014-08-28 17:58:05
【问题描述】:
我已经阅读了很多关于线程的内容,但不知道如何找到解决我的问题的方法。 首先让我介绍一下问题。我有需要处理的文件。主机名和文件路径位于两个数组中。
现在我想设置几个线程来处理文件。要创建的线程数基于三个因素:
A) 在所有情况下,最大线程数不能超过唯一主机名的数量。
B) 具有相同主机名的文件必须按顺序处理。 IE 我们不能同时处理 host1_file1 和 host1_file2。 (数据完整性将面临风险,这是我无法控制的。
C) 用户可以限制可用于处理的线程数。线程的数量仍然受到上面的条件 A 的限制。这纯粹是因为如果我们有大量主机,比如说 50 台......我们可能不希望同时处理 50 个线程。
在上面的示例中,最多可以创建 6 个线程。
最佳处理程序如下所示。
public class file_prep_obj
{
public string[] file_paths;
public string[] hostname;
public Dictionary<string, int> my_dictionary;
public void get_files()
{
hostname = new string[]{ "host1", "host1", "host1", "host2", "host2", "host3", "host4","host4","host5","host6" };
file_paths=new string[]{"C:\\host1_file1","C:\\host1_file2","C:\\host1_file3","C:\\host2_file1","C:\\host2_file2","C:\\host2_file2",
"C:\\host3_file1","C:\\host4_file1","C:\\host4_file2","C:\\host5_file1","C:\\host6_file1"};
//The dictionary provides a count on the number of files that need to be processed for a particular host.
my_dictionary = hostname.GroupBy(x => x)
.ToDictionary(g => g.Key,
g => g.Count());
}
}
//This class contains a list of file_paths associated with the same host.
//The group_file_host_name will be the same for a host.
class host_file_thread
{
public string[] group_file_paths;
public string[] group_file_host_name;
public void process_file(string file_path_in)
{
var time_delay_random=new Random();
Console.WriteLine("Started processing File: " + file_path_in);
Task.Delay(time_delay_random.Next(3000)+1000);
Console.WriteLine("Completed processing File: " + file_path_in);
}
}
class Program
{
static void Main(string[] args)
{
file_prep_obj my_files=new file_prep_obj();
my_files.get_files();
//Create our host objects... my_files.my_dictionary.Count represents the max number of threads
host_file_thread[] host_thread=new host_file_thread[my_files.my_dictionary.Count];
int key_pair_count=0;
int file_path_position=0;
foreach (KeyValuePair<string, int> pair in my_files.my_dictionary)
{
host_thread[key_pair_count] = new host_file_thread(); //Initialise the host_file_thread object. Because we have an array of a customised object
host_thread[key_pair_count].group_file_paths=new string[pair.Value]; //Initialise the group_file_paths
host_thread[key_pair_count].group_file_host_name=new string[pair.Value]; //Initialise the group_file_host_name
for(int j=0;j<pair.Value;j++)
{
host_thread[key_pair_count].group_file_host_name[j]=pair.Key.ToString(); //Group the hosts
host_thread[key_pair_count].group_file_paths[j]=my_files.file_paths[file_path_position]; //Group the file_paths
file_path_position++;
}
key_pair_count++;
}//Close foreach (KeyValuePair<string, int> pair in my_files.my_dictionary)
//TODO PROCESS FILES USING host_thread objects.
}//Close static void Main(string[] args)
}//Close Class Program
我想我所追求的是关于如何编写符合上述规范的线程处理例程的指南。
【问题讨论】:
-
+1 可以很好地展示您的问题。
-
@Complexity 谢谢.. 一张图片确实有 1000 个字。
-
想到的东西。你的阵列总是这样建立的吗?我的意思是:“数组 A 中索引 0 处的项目是否始终与数组 B 中索引 0 处的项目相对应,并且对于所有索引都是如此”?
-
我看到你在你的问题上付出了很多努力。但我没有看到任何问题......您面临的具体问题是什么?什么没用,你试过什么?标题也不是描述性的。
-
@PeterH:你真的需要多线程吗?在处理磁盘绑定 IO 时,您不会从多线程中受益,除非您的硬件已为此设置。见:stackoverflow.com/a/902455/324260
标签: c# multithreading task-parallel-library task async-await