2

我需要从另一个线程访问TextBoxes我的WPF应用程序,但我遇到了一个异常。Dispatcher我知道,每个 UI 控件和方法中都有一个属性BeginInvoke,但我不知道如何从中获取值TextBoxes

所以,这里是代码:

private void TestConnection_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var task = new Task(() => TryConnect());
                task.Start();
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message); 
            }
        }
        void TryConnect()
        {
            try
            {
                string con_str = "Server=" + Ip.Text + ";Port=" + Port.Text +
                ";Database=hospital;Uid=" + login.Text + 
                ";Pwd=" + password.Text + ";";
                using (MySqlConnection mcon = new MySqlConnection(con_str))
                {
                    mcon.Open();
                    MessageBox.Show("Connection is OK!");
                    mcon.Close();
                }
            }
            catch (MySqlException ex)
            {
                MessageBox.Show(ex.ErrorCode.ToString() + " " + ex.Message);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }
4

2 回答 2

2

如果您创建所需值的副本,那么您应该能够访问它们:

string username = login.Text, password = password.Text, ip = Ip.Text, port = Port.Text;
var task = new Task(() => TryConnect(username, password, ip, port));

和:

void TryConnect(string username, string password, string ip, string port) 
{
    // ...
}

像这样在本地复制值意味着您不需要从后台线程访问 UI 元素。

于 2013-10-22T22:29:56.593 回答
2

要回答您的问题,请将连接字符串从任务操作中移出:

        private void TestConnection_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            string con_str = "Server=" + Ip.Text + ";Port=" + Port.Text + ";Database=hospital;Uid=" + login.Text + ";Pwd=" + password.Text + ";";

            var task = new Task(() => TryConnect(con_str));
            task.Start();
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message);
        }
    }
    void TryConnect(string con_str)
    {
        try
        {

            using (MySqlConnection mcon = new MySqlConnection(con_str))
            {
                mcon.Open();
                MessageBox.Show("Connection is OK!");
                mcon.Close();
            }
        }
        catch (MySqlException ex)
        {
            MessageBox.Show(ex.ErrorCode.ToString() + " " + ex.Message);
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message);
        }
    }

但是你在这段代码中有很多问题。

  • WPF 中的代码不是“最佳实践”尝试看看这个:http: //msdn.microsoft.com/en-us/magazine/dd419663.aspx

  • 另一个线程上的 MessageBox 会导致很多痛苦。

  • 您正在尝试捕获任务创建周围的异常,这不会捕获操作内引发的异常。试试这个:

        private void TestConnection_Click(object sender, RoutedEventArgs e)
    {
        string con_str = "Server=" + Ip.Text + ";Port=" + Port.Text + ";Database=hospital;Uid=" + login.Text + ";Pwd=" + password.Text + ";";
        var dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
        var task = new Task(() => TryConnect(con_str));
        task.ContinueWith(task1 =>
            {
                //TODO Handle exception
                System.Diagnostics.Trace.WriteLine(task1.Exception);
                //or if you really want an messageBox, pass it back to the ui thread
                dispatcher.Invoke(() => MessageBox.Show(task1.Exception.Message));
    
            }, TaskContinuationOptions.OnlyOnFaulted);
        task.Start();
    }
    
于 2013-10-22T22:32:21.263 回答