1
private void Thread1_Exe()
{
    try
    {
        int sleepValT1 = Convert.ToInt32(listBoxT2.SelectedValue);
        int StartLoop = 0;
        int EndLoop = 10000;

        for (int i = StartLoop; i <= EndLoop; i++)
        {
            Dispatcher.BeginInvoke(
            new Action(() => listboxE1.Items.Add("T1: Execution Count> " + i.ToString())));
            Thread.Sleep(sleepValT1);
        }

    }
    catch (Exception Ex)
    {
        MessageBox.Show(Ex.Message);
    }
}

上記の関数を別のスレッドで呼び出そうとしていました

private void thread1_Click(object sender, RoutedEventArgs e)
{
    threadBtn1.IsEnabled = false;
    Thread t1 = new Thread(new ThreadStart(Thread1_Exe));

    t1.Start();
}

しかし、リストボックスから値を選択して変数に保存しようとすると例外が発生し、その値を渡そうとします

Thread.Sleep()

別のスレッドがこのオブジェクトを所有しているという例外が常に発生します。多くのことを試しました。私が間違っているところを助けてください。

ありがとう

4

2 に答える 2

3

あなたの問題は、バックグラウンド スレッドから UI コントロールにアクセスしていることです。UI はシングルスレッドになる傾向があるため、コントロールへのアクセスが常に UI スレッドを介して行われるように調整する必要があります。

あなたができる最も簡単なことは、新しいスレッドを開始する前にリストボックスから値を読み取ることです:

private void Thread1_Exe(int sleepVal)
{
    try
    {
        int StartLoop = 0;
        int EndLoop = 10000;


        for (int i = StartLoop; i <= EndLoop; i++)
        {

            Dispatcher.BeginInvoke(
            new Action(() =>
            listboxE1.Items.Add("T1: Execution Count> " + i.ToString())));
            Thread.Sleep(sleepVal);
        }

    }
    catch (Exception Ex)
    {
        MessageBox.Show(Ex.Message);
    }
}

private void thread1_Click(object sender, RoutedEventArgs e)
{

    threadBtn1.IsEnabled = false;

    int sleepValT1 = Convert.ToInt32(listBoxT1.SelectedValue);
    Thread t1 = new Thread(() => Thread1_Exe(sleepValT1));

    t1.Start();
}

その他の代替手段には、ディスパッチャ スレッドを介してコントロールにアクセスすることが含まれます。

private void Thread1_Exe()
{
    try
    {
        int sleepValT1;
        listBoxT1.Dispatcher.Invoke(() => sleepValT1 = Convert.ToInt32(listBoxT1.SelectedValue));
        int StartLoop = 0;
        int EndLoop = 10000;


        for (int i = StartLoop; i <= EndLoop; i++)
        {

            Dispatcher.BeginInvoke(
            new Action(() =>
            listboxE1.Items.Add("T1: Execution Count> " + i.ToString())));
            Thread.Sleep(sleepValT1);
        }

    }
    catch (Exception Ex)
    {
        MessageBox.Show(Ex.Message);
    }
}

private void thread1_Click(object sender, RoutedEventArgs e)
{

    threadBtn1.IsEnabled = false;

    Thread t1 = new Thread(() => Thread1_Exe());

    t1.Start();
}

一般に、スレッド間で変更可能な状態をできるだけ共有しないようにして、物事を簡単に推論できるようにする必要があります。

于 2016-02-17T14:52:21.273 に答える