在其他线程wpf中访问ui元素

问题描述 投票:2回答:2

我需要从另一个线程访问我的TextBoxes应用程序中的WPF,我有一个例外。我知道,每个UI控件和Dispatcher方法都有一个属性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);
            }
        }
c# wpf multithreading
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元素。


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(); }
© www.soinside.com 2019 - 2024. All rights reserved.