parallel.invoke在Winform和控制台应用程序中的行为方式不同

时间:2012-07-10 08:12:08

标签: c# winforms parallel-processing console backgroundworker

我最近构建了一个原型c#console应用程序,用于并行读取四个仪器的测量值(在同一个TimeStamp上),我使用parallel.invoke命令这样做,结果每次都很好。后来我尝试使用Winformsbackgroundworker中实现相同的概念。所以在我的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();
}

2 个答案:

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

我个人会选择这个选项。