0

私はこの機能を持っています:

private void cpuView()
        {
            if (pauseContinueDoWork == true)
            {
            }
            else
            {
                Computer myComputer = new Computer();
                myComputer = new Computer(settings) { CPUEnabled = true };

                myComputer.Open();
                Trace.WriteLine("");
                foreach (var hardwareItem in myComputer.Hardware)
                {
                    if (hardwareItem.HardwareType == HardwareType.CPU)
                    {
                        hardwareItem.Update();
                        foreach (IHardware subHardware in hardwareItem.SubHardware)
                            subHardware.Update();

                        foreach (var sensor in hardwareItem.Sensors)
                        {
                            settings.SetValue("sensor", sensor.Value.ToString());
                            if (sensor.SensorType == SensorType.Temperature)
                            {
                                sensor.Hardware.Update();
                                settings.GetValue("sensor", sensor.Value.ToString());
                                label17.Text = sensor.Value.ToString() + "c";//String.Format("{0} Temperature = {1}c", sensor.Name, sensor.Value.HasValue ? sensor.Value.Value.ToString() : "no value");
                                tempCpuValue = sensor.Value;
                                if (sensor.Value > 60)
                                {
                                    Logger.Write("The Current CPU Temperature Is ===> " + sensor.Value);
                                    button1.Enabled = true;
                                }
                                int t = label17.Text.Length;
                                if (t >= 4)
                                {
                                    label17.Location = new Point(50, 50); // not working to check everything about the locations \\

                                }
                                else
                                {
                                    label17.Location = new Point(50, 50);
                                }

                                break;
                            }
                        }
                    }
                }
            }
        }

そして、私はこの関数をバックグラウンドワーカー(DoWorkイベント)で呼び出しています:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            while (true)
            {

                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    if (tempCpuValue >= (float?)nud1.Value || tempGpuValue >= (float?)nud1.Value)
                    {
                        soundPlay = true;
                        blinking_label();
                        NudgeMe();
                    }
                    else
                    {
                        soundPlay = false;
                        stop_alarm = true;

                    }
                    cpuView();
                    gpuView();
                    Thread.Sleep(1000);
                }
            }
        }

この場合の例外は、次の行のcpuview関数にあります。

label17.Text = sensor.Value.ToString() + "c";

エラーメッセージは次のとおりです。クロススレッド操作が無効です:コントロール'label17'は、作成されたスレッド以外のスレッドからアクセスされました。

例外メッセージ:

System.InvalidOperationException was unhandled by user code
  HResult=-2146233079
  Message=Cross-thread operation not valid: Control 'label17' accessed from a thread other than the thread it was created on.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Control.get_Handle()
       at System.Windows.Forms.Control.set_WindowText(String value)
       at System.Windows.Forms.Control.set_Text(String value)
       at System.Windows.Forms.Label.set_Text(String value)
       at HardwareMonitoring.Form1.cpuView() in d:\C-Sharp\HardwareMonitoring\HardwareMonitoring\Hardwaremonitoring\Form1.cs:line 378
       at HardwareMonitoring.Form1.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in d:\C-Sharp\HardwareMonitoring\HardwareMonitoring\Hardwaremonitoring\Form1.cs:line 655
       at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
       at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
  InnerException: 

どうすれば解決/修正できますか?

4

2 に答える 2

2

バックグラウンドスレッドからUIスレッドへの呼び出しを行っています。BeginInvokeコントロールをデリゲートで更新するか、メソッドを使用するには、コントロールで使用する必要がありますReportProgress

例えば:

public delegate void InvokeDelegate();

private void DoWork()
{
    label17.BeginInvoke(new InvokeDelegate(InvokeMethod));
}

public void InvokeMethod()
{
   label17.Text = "I execute on the UI thread!";
}
于 2013-03-02T23:30:02.233 に答える
1

バックグラウンドスレッドからUIにアクセスしようとしています。したがって、「クロススレッド操作が無効です:」というメッセージが表示されます。

バックグラウンドワーカーからUIスレッドにイベントを送信し、UIInvokeの更新に使用する必要があります。ここでは、拡張メソッドとして実装しているため、任意のコントロールから呼び出すことができます。

public static void InvokeIfRequired(this Control control, Action action)
{
    if (control.InvokeRequired)
    {
        control.Invoke(action);
    }
    else
    {
        action();
    }
}

control更新するUI要素はどこにあり、action()呼び出すメソッドです。次に、次のように呼び出すことができます。

this.label17.InvokeIfRequired(() => this.label17.UpdateLabel(sensor.Value.ToString() + "c"));

private static void UpdateLabel(this Label label, string newValue)
{
    label.Text = newValue;
}
于 2013-03-02T23:37:24.407 に答える