我需要从另一个线程访问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);
}
}
答案 0 :(得分: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元素。
答案 1 :(得分: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();
}