Vb.net net 4.0中的并行编程
我一直在阅读并行编程,甚至现在对整个概念仍然有点困惑。假设我有一个项目,大约有5个类,它们相互作用,在方法中有局部变量,在单个类中所有方法都可以访问变量,甚至有1或2个变量可以通过实例化访问所有类。 现在使用线程,我知道如果没有应用锁定,全局变量将被多个线程覆盖,但是方法/函数的局部变量不会,对吗? 因此,如果我多次运行该项目,意味着作为一个新进程,那么方法和变量将是线程安全的,不会发生数据损坏? 因此,要使用任务工厂实现并行编程,如果我创建了一个基本上创建任务的项目,并且每个任务基本上运行另一个项目的实例,那么变量和数据不应该是线程安全的,并且不会被损坏吗? 但是,如果我有输出文件,并且它们以output&datetime.now.tostring命名,会不会有冲突问题,我会问这个问题,因为我知道在尝试时看到了这种情况Vb.net net 4.0中的并行编程,vb.net,visual-studio-2010,parallel-processing,Vb.net,Visual Studio 2010,Parallel Processing,我一直在阅读并行编程,甚至现在对整个概念仍然有点困惑。假设我有一个项目,大约有5个类,它们相互作用,在方法中有局部变量,在单个类中所有方法都可以访问变量,甚至有1或2个变量可以通过实例化访问所有类。 现在使用线程,我知道如果没有应用锁定,全局变量将被多个线程覆盖,但是方法/函数的局部变量不会,对吗? 因此,如果我多次运行该项目,意味着作为一个新进程,那么方法和变量将是线程安全的,不会发生数据损坏? 因此,要使用任务工厂实现并行编程,如果我创建了一个基本上创建任务的项目,并且每个任务基本上运行另一
dim factory as new taskfactory
factory.startnew(addressof projectinstance.main)
这也许是你们大多数人的常识,所以请对这里的批评保持温和。谢谢你的回复
编辑:
这是其中一个类中的文件创建模块:
Private Sub createXML()
num += 1
Dim fileList As New ArrayList
Dim counter As Integer = 0
Dim file As String = Module1.infile
xmlfile = directoryPath & "\Feed" & DateTime.Now.ToUniversalTime.ToString("yyyyMMddhhmmss") & endExtension
fileList.Add(xmlfile)
Thread.Sleep(2000)
Dim doc As XmlDocument = New XmlDocument
xwriter = New XmlTextWriter(xmlfile, Encoding.UTF8)
xwriter.Formatting = Formatting.Indented
xwriter.Indentation = 2
xwriter.WriteStartDocument(True)
xwriter.WriteStartElement("Posts")
Dim j As Integer = 0
For i As Integer = 0 To gXmlList.Count() - 1
j += 1
parseXML(gXmlList(i))
..这是单程序多数据。实际上,您为每个任务创建了一个单独的程序或对象图(一个任务在一个线程上被调度)。对象图全局的变量实例将很好(因此没有静态全局变量),但仍然需要担心文件等共享资源 解决这类问题的一种方法是为每个任务实例分配一个唯一的ID或“rank”,并让它使用它来标识资源并命名它们。在您的文件示例中,每个任务将输出一个名为myoutput_{rank}.txt的文件。如果您真正想要的是一个文件,那么您的应用程序必须实现一个后处理、聚合阶段,在该阶段合并结果。这在并行结束后依次发生。这就像一张地图/地图。您的每个并行任务都运行相同的“程序”,将一些输入数据映射到输出数据集(在您的案例中是一个文件),然后在单独的步骤中,将结果减少或聚合到最终答案中 下面是一个例子:
static void Main()
{
const int maxJobs = 10;
// Run jobs and wait...
List<Task> tasks = new List<Task>();
for (int rank = 0; rank < maxJobs; rank++)
tasks.Add(Task.Factory.StartNew((r) => { new MyApp().Main((int)r); }, rank));
Task.WaitAll(tasks.ToArray());
// Aggregate results...
StringBuilder sb = new StringBuilder();
for (int rank = 0; rank < maxJobs; rank++)
sb.AppendLine(File.ReadAllText("results_" + rank + ".txt"));
Console.WriteLine(sb.ToString());
File.WriteAllText("results_final.txt", sb.ToString());
Console.ReadLine();
}
public class MyApp
{
public void Main(int rank)
{
Console.WriteLine("Starting {0}", rank);
File.WriteAllText("results_" + rank + ".txt", "result data " + rank);
}
}
static void Main()
{
const int maxJobs=10;
//运行作业并等待。。。
列表任务=新列表();
for(int-rank=0;rank{newmyapp().Main((int)r);},rank));
Task.WaitAll(tasks.ToArray());
//聚合结果。。。
StringBuilder sb=新的StringBuilder();
for(int-rank=0;rank
MyApp类可以有任意多个状态。它甚至可以与子对象共享该状态,但它不能具有静态状态,也不能与MyApp外部定义的读/写全局对象共享状态
具有只读全局状态是可以的。例如,所有MyApp实例都可以从单个文件读取输入数据。不好的是让MyApp的多个实例读写(单个)全局变量、对象实例或其他资源(如文件),而不实现某种形式的协调(如锁)
在上面的示例中,每个任务都创建一个本地结果{rank}.txt文件。在单独的聚合步骤中,将这些内容合并到单个结果文件results_final.txt中。不可能并行执行此操作,因为这样所有任务都将写入单个全局资源
这本书和您可以在这里找到的示例中介绍了许多这些概念。MSDN上也提供了该内容(免费)
感谢您的回复,非常感谢……MyApp中定义的globals将包括我正在生成的输出文件,因此从技术上讲,这样就可以了……因为每个任务都有一个输入文件,并使用该输入文件创建相应的输出文件。是这样吗?我更新了我的答案。结果{rank}.txt文件不是全局文件,而是每个任务的本地文件。如果您想要一个results.txt文件,则该文件将被视为全局状态。请注意,全局只读状态是OK。全局写入或读/写不可用。