-1

私はいくつかの温度測定を行う必要がある学校のプロジェクトに取り組んでいます。タスクは、いくつかの温度をランダムに作成し、平均を計算することです。私のコードは次のとおりですが、スレッドに問題があります。ウィンドウ ハンドルが作成される前にオブジェクトを呼び出すことはできません。ネットを検索したところ、UI の更新にはバックグラウンド ワーカーの方が便利であることがわかりました。私はまだ学校に通い始めたばかりなので、プログラミングのスキルはまだありません。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Threading;

namespace Temperatur
{
    public partial class Form1 : Form
    {
        static Random rnd = new Random();
        static ArrayList tempList = new ArrayList();
        static SemaphoreSlim w, e, b;

        public Form1()
        {
            InitializeComponent();

            w = new SemaphoreSlim(1);
            e = new SemaphoreSlim(0);
            b = new SemaphoreSlim(6);

            Thread t1 = new Thread(randomNr);
            t1.Start();

            Thread t2 = new Thread(gennemsnit);
            t2.Start();
        }

        public void randomNr()
        {
            //Thread.Sleep(100);
            for (int i = 0; i < 10; i++)
            {
                //b.Wait();
                //w.Wait();
                int number = rnd.Next(36, 42);
                tempList.Add(number);

                listBox1.BeginInvoke((MethodInvoker)delegate
                {
                    listBox1.Items.Add(number);
                });
                //w.Release();
                //e.Release();
            }
        }

        public void gennemsnit()
        {
            double avg = 0;
            double nb = 0;
            //Thread.Sleep(200);

            for (int i = 0; i < tempList.Count; i++) //i < tempList.Count
            {
                //e.Wait();
                //w.Wait();
                nb += Convert.ToDouble(tempList[i]);
                avg = nb / tempList.Count;

                listBox2.Invoke((MethodInvoker)delegate //listbox2.invoke
                {
                    listBox2.Items.Add(avg);
                });
                //w.Release();
                //b.Release();
            }
        }
    }
}
4

3 に答える 3

0

あなたのコードが何をしようとしているのかはわかりませんが、あなたの仕事はとても簡単です。スレッドについて特に心配する必要はありません。簡単にするために、1秒ごとに実行するようにタイマーをスケジュールし、乱数を選択して温度を読み取り、UIで更新することができます。フォーム コントロール (System.Windows.Forms.Timer) からタイマーを選択すると、起動時に呼び出される関数から UI を直接更新できます。System.Timers.Timer のタイマーを使用する場合は、BeginInvoke を使用してリストを更新する必要があります。

于 2013-11-06T14:06:17.153 に答える
0

ウィンドウ ハンドルが作成される前にオブジェクトを呼び出すことはできません。

Form のコンストラクターでスレッドを開始しないでください。代わりに Load() または Shown() イベントを使用します。

    public Form1()
    {
        InitializeComponent();

        w = new SemaphoreSlim(1);
        e = new SemaphoreSlim(0);
        b = new SemaphoreSlim(6);

        this.Load += new EventHandler(Form1_Load);
    }

    void Form1_Load(object sender, EventArgs e)
    {
        Thread t1 = new Thread(randomNr);
        t1.Start();

        Thread t2 = new Thread(gennemsnit);
        t2.Start();
    }
于 2013-11-06T16:04:13.687 に答える