2012-07-10 67 views
-1

我最近构建了一个原型c#控制台应用程序,用于从四个仪器并行读取测量结果(在同一个TimeStamp上),我使用了parallel.invoke命令来执行此操作,结果每次都很好。后来我试图用backgroundworkerWinforms中实现相同的概念。因此,在我的DoWork中,我将这个parallel.invoke称为运行这四个函数来获取读数,但结果经过这么长时间后才会返回,并且它们不在同一时间戳上,我没有使用背景工人尝试它,但是我得到了相同的结果。任何人都知道为什么parallel.invoke表现如此。它在控制台应用程序中正常工作,而不是在winform中?还有一种方法可以确保多个async procces执行并行运行?我很难理解这一点,请在这里帮助我。任何意见将不胜感激!parallel.invoke在Winform和控制台应用程序中的行为有所不同

更新:抱歉,我之前并行调用了 后来我将其更改为任务,但行为相同。

控制台应用程序

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

你在使用什么硬件?你有多少个CPU核心? – 2012-07-10 08:15:26

+0

它的英特尔核心-i5 – user1514077 2012-07-10 08:18:27

+1

一个简单的代码示例,包括控制台代码和Windows窗体代码在这里真的很有帮助。 – 2012-07-10 08:18:49

回答

0

我会处理这样的问题:在自己的static类中提取工作并行读取代码,然后从bo th控制台应用程序 winforms应用程序,并看看会发生什么。你应该发现自己的东西既可以是双向的,也可以根本不工作(因为你调用了相同的代码)。

+0

我尝试了你的sugesstion,但行为仍然是一样的。我使用同步I/O。你认为这会导致问题吗?这些读取在GUI应用程序中是连续的(正如我在仪器软件提供的IO monier中检查的那样),但是在控制台应用程序 – user1514077 2012-07-10 12:36:33

+0

Uhm中再次正常工作。要捣鼓一些代码... – Alex 2012-07-10 13:31:34

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(); 
} 

我会亲自去使用此选项。

相关问题