报告类和线程之间后台工作者的进度

时间:2012-07-26 01:07:37

标签: c# wpf progress-bar backgroundworker

以下是我处理与串行设备的连接和交互的类的代码。我从另一个类调用connect函数,如下所示。我的问题是:更新我的进度条的最佳方法是什么,它位于与初始化后台工作者不同的类上?我遇到了问题,因为我正在尝试更新跨线程和跨类的内容。将表单类作为参数传递给我的connect函数,但是我必须通过后台worker和report progress函数传递它;它只是凌乱和不洁净。有一个更好的方法吗?任何帮助都表示赞赏,并提前感谢。

我从(也是我的WPF类)调用连接函数的类:

public partial class agentRadio : Window
{
    private void connectButton_Click(object sender, RoutedEventArgs e) //Connect button clicked
    {
        agentradioread.connect((string)portsOpen.SelectedValue, this);
    }
}

处理我的串行交互的类:

class agentRadioRead //Handles connection and reading of device values
{
    /*Local variable declarations*/
    SerialPort agentSerial;
    BackgroundWorker connectWorker;

    string resultMessage = "Error: The connect function has completed without setting this status message properly.";
    byte[] data = new byte[2246];

    /*Public methods*/

    public void connect(string selectedPort, agentRadio agentR) //Connects device, reads values, stores values, displays status message
    {
        agentSerial = new SerialPort(selectedPort, 9600, Parity.None, 8, StopBits.One);
        connectWorker = new BackgroundWorker();
        //connectWorker.WorkerReportsProgress = true;
        connectWorker.DoWork += new DoWorkEventHandler(initialRead);
        //connectWorker.ProgressChanged += new ProgressChangedEventHandler(reportProgress);

        connectWorker.RunWorkerAsync(agentR);
    }

    /*Private methods*/

    void initialRead(object sender, DoWorkEventArgs e)
    {
        agentSerial.Open();
        agentSerial.BaseStream.Flush();

        byte[] result = new byte[7];
        byte questionMark = 63;
        agentSerial.BaseStream.WriteByte(questionMark);

        System.Threading.Thread.Sleep(100);
        agentSerial.BaseStream.Read(result, 0, 7);

        string system = "";
        foreach (byte letter in result)
        {
            system += Convert.ToChar(letter).ToString();
        }

        bool read = readPort();

        if (read)
        {
            int i = 1;
            foreach (byte value in data)
            {
                storeData(i, value);
                i++;
            }
        }

        MessageBox.Show(resultMessage, "Status Message", MessageBoxButton.OK, MessageBoxImage.Information);
    }

    bool readPort()
    {
        bool succesfulRead = false;

        agentSerial.BaseStream.Flush();
        agentSerial.BaseStream.Write(Global.READ_VALUES, 0, Global.READ_VALUES.Length); //begin read values

        byte key = (byte)agentSerial.BaseStream.ReadByte();

        if (Global.START_COMMAND == key) //Verify continue key
        {
            for (int i = 0; i < 2246; i++) //Loop through values
            {
                try
                {
                    data[i] = (byte)agentSerial.BaseStream.ReadByte();
                    agentSerial.BaseStream.Write(Global.GO_AHEAD, 0, Global.GO_AHEAD.Length);
                    agentSerial.BaseStream.Flush();
                }
                catch
                {
                    resultMessage = "An error occured, while reading the device settings." + i;
                    break;
                }
            }
            if (data[2245] != Global.FINISH_COMMAND)
            {
                resultMessage = "An error occured, while reading the device settings." + 2245;
            }
            else
            {
                succesfulRead = true;
            }
        }
        else //Key failed and displays error
        {
            resultMessage = "An error occured, are you sure you are trying to connect to an Agent (Radio Version)? If so make sure you have followed the steps listed above.";
        }

        return succesfulRead;
    }

    void storeData(int iteration, byte value)
    {
        if (iteration > 0 && iteration < 385) //read schedule
        {
            double pos = (iteration - 1) / 48;

            int i = (int)Math.Floor(pos);
            int j = (iteration - 1) - (i * 48);

            Create.schedule[i, j] = value;
        }

        if (iteration > 384 && iteration < 1285) //read alarm history
        {
            double pos = (iteration - 385) / 9;

            int i = (int)Math.Floor(pos);
            int j = (iteration - 385) - (i * 9);

            Create.alarms[i, j] = value;
        }

        if (iteration > 1284 && iteration < 1345) //read error log
        {
            double pos = (iteration - 1285) / 6;

            int i = (int)Math.Floor(pos);
            int j = (iteration - 1285) - (i * 6);

            Create.errors[i, j] = value;
        }

        if (iteration > 1344 && iteration < 1945) //read voltage history
        {
            double pos = (iteration - 1345) / 6;

            int i = (int)Math.Floor(pos);
            int j = (iteration - 1345) - (i * 6);

            Create.voltage[i, j] = value;
        }

        if (iteration > 1944 && iteration < 1973) //read holidays
        {
            Create.holidays[iteration - 1945] = value;
        }

        if (iteration > 1972 && iteration < 2168) //read message sequences
        {
            double pos = (iteration - 1973) / 15;

            int i = (int)Math.Floor(pos);
            int j = (iteration - 1973) - (i * 15);

            Create.messages[i, j] = value;
        }

        if (iteration > 2167 && iteration < 2196) //read message info
        {
            Create.recordings[iteration - 2168] = value;
        }

        if (iteration > 2195 && iteration < 2246) //read sysval
        {
            Create.sysval[iteration - 2196] = value;
        }

        if (iteration == 2246 && value == Global.FINISH_COMMAND)
        {
            if (Global.restoring)
            {
                resultMessage = "Your device has been succesfully restored.";
            }
            else
            {
                resultMessage = "Your device has been succesfully connected, and all settings have been loaded from the device.";
            }
        }
        else
        {
            resultMessage = "An error occured, while reading the device settings." + "Storing";
        }
    }

    void reportProgress(object sender, ProgressChangedEventArgs e)
    {

    }
}

1 个答案:

答案 0 :(得分:0)

我会反过来这样做。 从agentRadio窗口中初始化工作线程 在agentRadioRead类中具有与设备交互相关的所有功能 从中引出所有引用表单窗口的代码。 创建此agentRadioRead类的对象并将其传递给工作线程。 使用workerthread的reportprogress事件来报告agentRadio窗口的状态更改。 让agentRadio中的事件处理程序进行任何UI更新。