这是一个很长的问题,它是一个愚蠢的问题,对于我的应用程序并不重要,但仍然很奇怪。我觉得如果我理解它,将有助于我更好地理解c#/ wpf。
我正在开发一个将excel文件加载到mysql的应用程序。我想在日志文本框中显示何时删除数据库中的行。将新数据加载到数据库后,日志文本框应显示一条消息,其中包含受影响的行数。
文本框绑定到
<TextBox x:Name="ConnectionLogTbx" Text="{Binding ConnectionLogText}" />
下面的代码(省略了一些行):ConnectionLogText附加了一个字符串。首先是日期时间+“已删除”。第二次受影响的行数。
插入数据库大约需要2秒钟。我希望出现的是第一个日志消息,然后停顿两秒钟(插入新行时),然后出现第二个日志消息。有趣的是,在插入操作之后,文本框会同时使用两个字符串进行更新。插入操作之前没有日志消息。所显示的时间与预期的一样,中间大约有2秒。
但是,如果我在属性的设置器中添加messagebox.show(并因此创建了pause),则应用程序将按预期运行。第一个日志消息出现在文本框中,单击消息框后,将执行插入操作,然后出现第二个日志消息。
WPF似乎需要休息一下才能更新文本框,但这与我对WPF的了解不一致。
有人可以帮我吗?
public partial class MainWindow : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string connectionLogText ="";
public string ConnectionLogText
{
get { return connectionLogText; }
set
{
if (value != connectionLogText)
{
connectionLogText = value;
OnPropertyChanged("ConnectionLogText");
//MessageBox.Show(""); //THIS IS THE MESSAGEBOX
}
}
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void BrowseImportFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
{
ImportFilePathTbx.Text = openFileDialog.FileName;
ImportFileBtn.IsEnabled = true;
}
}
private void ImportFileBtn_Click(object sender, RoutedEventArgs e)
{
string connString =
ConfigurationManager.ConnectionStrings["connSTring"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connString);
conn.Open();
//here the content of the current db table is deleted
conn.Close();
ConnectionLogText += DateTime.Now.ToString("hh:mm:ss.fff") + "
Deleted" + "\r\n";
conn.Open();
int numberOfRowsAffected = 0;
foreach (DataRow dataRow in table.Rows)
{
//new data inserted into database numberOfRowsAffected++;
}
conn.Close();
ConnectionLogText += DateTime.Now.ToString("hh:mm:ss.fff") + " " +
numberOfRowsAffected + " rows inserted" + "\r\n" ;
}
}
答案 0 :(得分:2)
您不能同时在同一线程上更新TextBlock
并从数据库中读取记录。
您应该在后台线程上执行数据库操作。最简单的方法是使用Task Parallel Library (TPL):
private async void ImportFileBtn_Click(object sender, RoutedEventArgs e)
{
string connString = ConfigurationManager.ConnectionStrings["connSTring"].ConnectionString;
await Task.Run(() =>
{
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
//here the content of the current db table is deleted
conn.Close();
}
});
ConnectionLogText += DateTime.Now.ToString("hh:mm:ss.fff") + " Deleted" + "\r\n";
int numberOfRowsAffected = 0;
await Task.Run(() =>
{
conn.Open();
foreach (DataRow dataRow in table.Rows)
{
//new data inserted into database numberOfRowsAffected++;
}
conn.Close();
});
ConnectionLogText += DateTime.Now.ToString("hh:mm:ss.fff") + " " + numberOfRowsAffected + " rows inserted" + "\r\n";
}