我最近构建了一个原型c#console应用程序,用于并行读取四个仪器的测量值(在同一个TimeStamp
上),我使用parallel.invoke命令这样做,结果每次都很好。后来我尝试使用Winforms
在backgroundworker
中实现相同的概念。所以在我的DoWork
我调用这个parallel.invoke运行四个函数来获取读数,但结果在这么长时间后返回并且它们不在同一时间戳上,我确实尝试了没有后台工作者但是我有相同的结果。任何人都知道为什么parallel.invoke表现如此?它在控制台应用程序中运行良好而不是winform?还有一种方法可以确保多个async procces
执行并行运行吗?我很难理解这一点,请帮帮我。任何意见将不胜感激!
更新:很抱歉这是混乱,我之前使用并行调用做了这个 后来我把它改成了任务,但行为是一样的。
控制台应用:
public static void funcc()
{
for (int i = 0; i < 5; i++)
{
rawData3 = fmio.IO.Read(4 * numReadings);
RawData3.Add(rawData3);
}
}
public static void funcd()
{
for (int i = 0; i < 5; i++)
{
rawData4 = fmio.IO.Read(4 * numReadings);
RawData4.Add(rawData4);
}
}
static void Main(string[] args)
{
//Parallel.Invoke(() => { funcb(); }, () => { funcc(); }, () => { funca(); }, () => { funcd(); });
var factory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
Task t1 = factory.StartNew(funca);
Task t2 = factory.StartNew(funcb);
Task t3 = factory.StartNew(funcc);
Task t4 = factory.StartNew(funcd);
t1.Wait();
t2.Wait();
t3.Wait();
t4.Wait();
WriteToFile(); // Writes Result to the file
}
在我的 Gui应用程序中,我正在backgroundWorker
中执行此操作。我具有与我在GUI应用程序中使用的上述定义相同的读取功能:
public static void funca()
{
for (int i = 0; i < 5; i++)
{
rawData = fmio.IO.Read(4 * numReadings); // Getting Data in Byte Array
RawData1.Add(rawData); // Putting it in ArrayList
}
}
public static void funcb()
{
for (int i = 0; i < 5; i++)
{
rawData2 = fmio.IO.Read(4 * numReadings);
RawData2.Add(rawData2);
}
}
private void btn_StartMeasurement_Click(object sender, EventArgs e)
{
if (!bwObj.IsBusy)
{
bw_Obj.RunWorkerAsync();
}
}
private void bw_Obj_DoWork_1(object sender, DoWorkEventArgs e)
{
//Parallel.Invoke(() => { funcb(); }, () => { funcc(); }, () => { funca(); }, () => { funcd(); });
var factoryA = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
var time = System.Diagnostics.Stopwatch.StartNew();
Task t1 = factoryA.StartNew(() => funca(Globls.numReadings, DMM));
Task t2 = factoryA.StartNew(() => funcb(Globls.numReadings, DMM2));
Task t3 = factoryA.StartNew(() => funcc(Globls.numReadings, DMM3));
Task t4 = factoryA.StartNew(() => funcd(Globls.numReadings, DMM4));
t1.Wait();
t2.Wait();
t3.Wait();
t4.Wait();
WriteToFile();
}
答案 0 :(得分:0)
我会处理这样的问题:在自己的static
类中提取工作并行读取代码,然后从控制台应用程序和 winforms应用程序中调用它,并且走着瞧吧。您应该发现自己的某些方面既可以双向运行,也可以根本不运行(因为您调用相同的代码)。
答案 1 :(得分:0)
这可以通过多种方式实施。如果您正在寻找并行执行bw_Obj_DoWork_1部分中的内容,那么我会考虑更改btn_StartMeasurement_Click并删除BackgroundWorker。
private void btn_StartMeasurement_Click(object sender, EventArgs e)
{
Task[] tasks = new Task[]
{
Task.Factory.StartNew(funca),
Task.Factory.StartNew(funcb),
Task.Factory.StartNew(funcc),
Task.Factory.StartNew(funcd)
};
Task writeTask = Task.Factory.ContinueWhenAll(tasks, (t) => writeToFile());
}
或者,您可以创建一个方法,我将其称为executeAndWrite,并使用btn_StartMeasurement_Click中的线程或任务来启动它们:
private void btn_StartMeasurement_Click(object sender, EventArgs e)
{
new Thread(executeAndWrite).Start();
}
private void executeAndWrite()
{
Parallel.Invoke(funca, funcb, funcc, funcd);
writeToFile();
}
我个人会选择这个选项。