【发布时间】:2021-01-20 02:23:33
【问题描述】:
我正在使用 BackgroundWorker() 在后台执行长时间运行的查询,同时我正在显示我的执行正在运行的弹出窗口。
这是我如何调用 bg_worker()
using System.Windows;
using System.ComponentModel;
using System.Threading;
using System;
using System.IO;
using System.Data.SqlClient;
using System.Windows.Input;
namespace TestEnvironment
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class ProgressBarTemplate : Window
{
private CreateProjectScreen _CreateProjectScreen;
private LoginScreen _LoginScreen;
public ProgressBarTemplate()
{
InitializeComponent();
}
public static int RunCalculationsMethod(string connectionstring, string foldername)
{
bool exists = Directory.Exists(foldername);
if (!exists)
{
Directory.CreateDirectory(foldername);
}
try
{
using (SqlConnection sqlConnection = new SqlConnection(connectionstring))
{
var calculations_query = "SELECT * FROM table1");
using SqlCommand sqlCommand = new SqlCommand(calculations_query, sqlConnection);
sqlConnection.Open();
sqlCommand.CommandTimeout = 60 * 10;
int NumbderOfRecords = sqlCommand.ExecuteNonQuery();
return NumbderOfRecords;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return -100;
}
}
private void Window_ContentRendered(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
int IsSuccessful = RunCalculationsMethod("Server=localhost;Database=DB_Name;Integrated Security=SSPI", String.Format("C:\\folder_path\\"));
}
void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// This is called on the UI thread when the DoWork method completes
// so it's a good place to hide busy indicators, or put clean up code
try
{
this.Close();
MessageBox.Show("DQ Calculations completed successfully", "Information", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
上面的代码放在一个叫做 ProgressBarTemplate() 的窗口中
我想要的是在按钮点击时调用 background_worker,在我的 MainWindow 中放置一个按钮
所以我的 MainWindow 有以下按钮点击
private void RunCalculationsButton_Click(object sender, RoutedEventArgs e)
{
//RunCalculationsMethod(SQLServerConnectionDetails(), String.Format("C:\\DQ_Findings_{0}", HomePageTab.Header.ToString().Split(" - ")[1]));
try
{
Application.Current.Dispatcher.Invoke((Action)delegate
{
ProgressBarTemplate win_progressbar = new ProgressBarTemplate();
win_progressbar.Show();
//RunCalculationsMethod(SQLServerConnectionDetails(), String.Format("C:\\DQ_folder_test\\Findings\\"));
}); // The code runs up to this point.
//The code below is not executed for a reason, which I am trying to solve with this question
List<SucessfulCompletion> reportsucessfulcompletion = new List<SucessfulCompletion>();
reportsucessfulcompletion = SuccessfulCalculationsTimestamp(SQLServerConnectionDetails());
if (reportsucessfulcompletion[0].Result==1)
{
//Enable is only if successfull
PreviewCalculationsButton.IsEnabled = true;
PreviewReportButton.IsEnabled = true;
//add textbox of sucess
TickButtonSymbolCalculations.Visibility = Visibility.Visible;
SQLSuccessfulTextCalculations.Visibility = Visibility.Visible;
XerrorSymbolCalculations.Visibility = Visibility.Hidden;
SQLFailedTextCalculations.Visibility = Visibility.Hidden;
SQLSuccessfulTextCalculations.Text = String.Format("Completed On: {0}", reportsucessfulcompletion[0].Timestampvalue);
}
else
{
//add textbox of fail
TickButtonSymbolCalculations.Visibility = Visibility.Hidden;
SQLSuccessfulTextCalculations.Visibility = Visibility.Hidden;
XerrorSymbolCalculations.Visibility = Visibility.Visible;
SQLFailedTextCalculations.Visibility = Visibility.Visible;
SQLFailedTextCalculations.Text = String.Format("Failed On: {0}", reportsucessfulcompletion[0].Timestampvalue);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
}
单击按钮时,我通过调用窗口 ProgressBarTemplate() 来启动 bg_worder。尽管在完成任务后代码生成一些文本并启用某些按钮的可见性,但它们并没有被执行。为什么会这样?我错过了什么吗?
【问题讨论】:
-
这是可怕的代码。我不知道 UI 何时结束,线程逻辑何时开始。您的代码可能会在调用方法(即 UI 线程)中完成所有操作。
-
@Bizhan 问题出在我的第一个代码 sn-p(又名 BG Worker)还是关于 MainWindow(第二个代码 sn-p)? :)
-
我认为您不应该通过调度程序创建进度条。您已经在按钮单击事件处理程序的 UI 线程中,因此您应该能够直接创建它。
-
@allan 如果你提到
Application.Current.Dispatcher.Invoke((Action)delegate { ...});我这样做是因为 C# 给我一个关于 STA 线程错误的错误 -
@NikSp 忘记 BGW。这是一个自 2012 年以来完全被
Task.Run取代的过时类。与其将计算放在进度窗口中,不如在click或rendered处理程序中使用简单的var results=await Task.Run(()=>SomeHeavyComputing());就足够了,允许您在之前更新 UI 和在没有Invoke的异步操作之后
标签: c# sql-server wpf