-1

我最近构建了一个原型 c# 控制台应用程序以并行读取来自四个仪器的测量值(在同一台上TimeStamp),我使用了 parallel.invoke 命令来执行此操作,每次结果都非常好。后来我尝试在Winformsusing中实现相同的概念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();
}
4

2 回答 2

0

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

于 2012-07-10T10:34:39.867 回答
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();
}

我个人会选择这个选项。

于 2013-03-25T02:32:42.977 回答