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

4

对 UI 元素的任何访问,无论是读取还是写入,都必须通过主 UI 线程调用。该线程可通过Dispatcher.

在您的代码中,我看到不是这种情况的一行:当您打电话时listBoxT2.SelectedValue

要修复错误,请在 Thread 上调用此代码Dispatcher并将其保存到局部变量:

int selectedValue;
listBoxT2.Dispatcher.Invoke(() => selectedValue = Convert.ToInt32(listBoxT2.SelectedValue));
   

其余代码应该可以正常工作。

于 2016-02-17T14:59:41.633 回答
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 回答