C# wpf) Indeterminate Progressbar не запускает вращающуюся анимацию и даже, кажется, блокирует общую производительность
Я принял решение хорошего человека, и оно работает нормально, чтобы обновить прогресс как определенный. Тем не менее, я испытываю трудности в использовании как неопределенный. Редко, вращающаяся анимация неопределенного Progressbar показывает, но в последнее время.
Я базовый ученик и не очень разбираюсь в асинхронности, работе в фоновом режиме (многопоточность). Поэтому, пожалуйста, прости мои плохие знания.
Что отличается от моего определенного кода, я использую this.Dispatcher.BeginInvoke(new Action(async() =>{...}))
потому что я столкнулся с исключением из-за ожидания кода внутри метода bwDoWork.
Что я хотел бы реализовать, так это то, что мое приложение работает намного быстрее, с отображением неопределенного индикатора выполнения основным потоком и фоновым рабочим, которые работают вместе.
Я очень ценю, кто-то консультирует меня с отличной проницательностью.
XAML-код окна прогресса Bar_forBasicWaiting:
<Window x:Class="progressBar_forBasicWaiting.ProgressDialog_forBasicWaiting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Blue Tiger Program v1.0"
ContentRendered="initBackgroundWorker"
Height="168.946" Width="518.001" MinHeight="100" MinWidth="350" ResizeMode="NoResize" Background="#FFFFFFFF" BorderThickness="0" WindowStartupLocation="CenterOwner" Icon="whitecross_icon.ico" ShowInTaskbar="False" SnapsToDevicePixels="True" Loaded="Window_Loaded" Visibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="40*"/>
<RowDefinition Height="100*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="pbHeader" Margin="0,0,0,1" Padding="5,0" Grid.Row="0" Grid.Column="0"
Text="{Binding Title,RelativeSource={RelativeSource FindAncestor,AncestorType=Window}}"
FontSize="15" FontWeight="Bold" Foreground="Black" Background="#FF7BD34E" Opacity="0">
</TextBlock>
<ProgressBar Name="pbStatus" Grid.Row="2" Grid.Column="0" Maximum="100" Value="0" Foreground="#FF65ADF1" Margin="114,10,104,63" BorderThickness="0" IsHitTestVisible="False" IsTabStop="False" ScrollViewer.VerticalScrollBarVisibility="Disabled" UseLayoutRounding="True" BorderBrush="{x:Null}" Background="#FFF0F0F0" IsIndeterminate="True" >
<ProgressBar.Effect>
<DropShadowEffect/>
</ProgressBar.Effect>
</ProgressBar>
<TextBlock x:Name="textBlockPercentageshow" Grid.Row="2" Grid.Column="0" Text="{Binding ElementName=pbStatus, Path=Value, StringFormat={}{0:0}%}" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.627,-1.083" Margin="218,10,213,61" Width="81" IsHitTestVisible="False" ScrollViewer.VerticalScrollBarVisibility="Disabled" Padding="29,5,0,0" UseLayoutRounding="True" SnapsToDevicePixels="True" Height="26" Visibility="Hidden" />
<TextBlock x:Name="textBlockProgressbartitle" HorizontalAlignment="Left" Margin="10,10,0,0" Grid.Row="1" TextWrapping="Wrap" Text="loading data.." VerticalAlignment="Top" Width="494" Height="25" IsHitTestVisible="False" UseLayoutRounding="True" SnapsToDevicePixels="True" ScrollViewer.VerticalScrollBarVisibility="Disabled" Padding="0,3,0,0"/>
<TextBlock x:Name="textBlockMessagewaitplease" HorizontalAlignment="Center" Margin="164,53,156,0" Grid.Row="2" TextWrapping="Wrap" VerticalAlignment="Top" Width="192" Height="32" IsHitTestVisible="False" ScrollViewer.VerticalScrollBarVisibility="Disabled" UseLayoutRounding="True" Text="Please wait.." Padding="5,5,0,0"/>
</Grid>
за CS-кодом прогресса Bar_forBasicWaiting окно находится,
namespace progressBar_forBasicWaiting {
public partial class ProgressDialog_forBasicWaiting : Window {
private static BackgroundWorker bw = null; // Background task handler
private static string progressHeaderText = "Pending ...";
private static string progressMessageText = "Starting ...";
private static int progressPercentage = 0;
public ProgressDialog_forBasicWaiting() {
bw = new BackgroundWorker();
bw.ProgressChanged += new ProgressChangedEventHandler(bwProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwRunWorkerCompleted);
SetProgressOptions(false, true); // set cancellation, report-progress states
InitializeComponent();
}
public void SetProgressOptions(bool can, bool rpt) {
bw.WorkerSupportsCancellation = can;
bw.WorkerReportsProgress = rpt;
}
public void AddDoWorkHandler(Action<object,DoWorkEventArgs> fn) {
bw.DoWork += new DoWorkEventHandler(fn);
}
public void AddProgressChangedHandler(Action<object,ProgressChangedEventArgs> fn) {
bw.ProgressChanged += new ProgressChangedEventHandler(fn);
}
public void AddProgressCompletedHandler(Action<object, RunWorkerCompletedEventArgs> fn) {
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(fn);
}
public void Start() {
bw.RunWorkerAsync();
}
public void UpdateProgress(int pct) {
progressPercentage = pct;
bw.ReportProgress(pct);
}
public void ChangeStatusMessage(string msg) {
progressMessageText = msg;
bw.ReportProgress(progressPercentage);
}
public void ChangeWindowTitle(string ttl) {
progressHeaderText = ttl;
bw.ReportProgress(progressPercentage);
}
private void initBackgroundWorker(object sender, EventArgs e) {
bw.RunWorkerAsync();
}
private void bwProgressChanged(object sender, ProgressChangedEventArgs e) {
pbHeader.Text = progressHeaderText;
pbStatus.Value = e.ProgressPercentage;
}
private void bwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Close();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
}
}
стартовый код из mainWindow есть,
private async void buttonGreenStart_Click(object sender, RoutedEventArgs e)
{
pb_forBasicWaiting = new ProgressDialog_forBasicWaiting();
pb_forBasicWaiting.Owner = this;
pb_forBasicWaiting.SetProgressOptions(false, true);
pb_forBasicWaiting.AddDoWorkHandler(bwDoWork);
pb_forBasicWaiting.Show();
}
Код DoWork из mainWindow есть,
void bwDoWork(object sender, DoWorkEventArgs e)
{
this.Dispatcher.BeginInvoke(new Action(async() =>
{
string localConnectionString = string.Format(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename= " + Environment.GetEnvironmentVariable("APPDATA") + @"\Blue Tiger" + @"\greendb_{0}.mdf;Integrated Security=True;Connect Timeout=30;User Instance=False;", textBoxGreenLogin.Text);
SqlConnection bwConn = new SqlConnection();
bwConn.ConnectionString = localConnectionString;
bwConn.Open();
SqlCommand load_mainpatientslistcomm = new SqlCommand();
load_mainpatientslistcomm.Connection = bwConn;
load_mainpatientslistcomm.CommandText = string.Format("SELECT patientid, patientname, registrationdate, birthyear, birthmonth, consultation_count, basicmemo FROM patientslist_pharmacy_{0}_{1}", comboBoxPharmacyid.SelectedItem.ToString(), textBoxGreenLogin.Text);
load_mainpatientslistcomm.CommandTimeout = 190;
SqlDataAdapter load_mainpatientslistda = new SqlDataAdapter(load_mainpatientslistcomm);
static_green_mainpatientslist_dt = new DataTable(string.Format("patientslist_pharmacy_{0}_{1}", comboBoxPharmacyid.SelectedItem.ToString(), textBoxGreenLogin.Text));
load_mainpatientslistda.Fill(static_green_mainpatientslist_dt);
byteAESKey = Convert.FromBase64String(static_AESKey);
byteAESIV = Convert.FromBase64String(static_AESIV);
foreach (DataRow row in static_green_mainpatientslist_dt.Rows)
{
string strpatientname = (string)row["patientname"].ToString();
bytepatientname = Convert.FromBase64String(strpatientname);
string decryptedpatientname = Green_MainWindow.DecryptStringFromBytes_Aes(bytepatientname, byteAESKey, byteAESIV);
row["patientname"] = decryptedpatientname;
}
bwConn.Close();
Service1Client client_countidea = new Service1Client();
int azuregreenideatotalcount = await client_countidea.CountIdeaOnServerAsync();
client_countidea.Close();
Service1Client client_countoverview = new Service1Client();
int azureoverviewtotalcount = await client_countoverview.CountOverviewOnServerAsync();
client_countoverview.Close();
Service1Client client_countoverview_tobedeleted = new Service1Client();
int azureoverviewtotalcount_tobedeleted = await client_countoverview_tobedeleted.CountOverviewTobeDeletedOnServerAsync();
client_countoverview_tobedeleted.Close();
if (azureoverviewtotalcount != localoverviewtotalcount)
{
if (localoverviewtotalcount == 0)
{
Service1Client client_copyoverviewfromserver = new Service1Client();
overviewarray_fromserver = await client_copyoverviewfromserver.OverviewArrayFromServerAsync();
client_copyoverviewfromserver.Close();
SqlConnection localoverviewupdateConn = new SqlConnection();
localoverviewupdateConn.ConnectionString = green_dataConnectionString;
localoverviewupdateConn.Open();
foreach (string single_overview in overviewarray_fromserver)
{
SqlCommand localoverviewupdatecomm = new SqlCommand();
localoverviewupdatecomm.Connection = localoverviewupdateConn;
localoverviewupdatecomm.CommandText = "INSERT INTO overview_keyword (immunity_markers) VALUES(@oimmunity)";
var localoverviewupdateda = new SqlDataAdapter(localoverviewupdatecomm);
localoverviewupdateda.SelectCommand.Parameters.Add(new SqlParameter("@oimmunity", SqlDbType.NVarChar));
localoverviewupdateda.SelectCommand.Parameters["@oimmunity"].Value = single_overview;
var localoverviewupdateds = new DataSet();
localoverviewupdateda.Fill(localoverviewupdateds);
}
localoverviewupdateConn.Close();
}
else
{
try
{
SqlDataAdapter localoverviewclearda = new SqlDataAdapter();
SqlConnection localoverviewclearConn = new SqlConnection();
localoverviewclearConn.ConnectionString = greenpharmacy_dataConnectionString;
localoverviewclearConn.Open();
string sql = "DELETE FROM overview_keyword";
localoverviewclearda.DeleteCommand = localoverviewclearConn.CreateCommand();
localoverviewclearda.DeleteCommand.CommandText = sql;
localoverviewclearda.DeleteCommand.ExecuteNonQuery();
localoverviewclearConn.Close();
}
catch (Exception)
{
}
Service1Client client_copyoverviewfromserver = new Service1Client();
overviewarray_fromserver = await client_copyoverviewfromserver.OverviewArrayFromServerAsync();
client_copyoverviewfromserver.Close();
SqlConnection localoverviewupdateConn = new SqlConnection();
localoverviewupdateConn.ConnectionString = greenpharmacy_dataConnectionString;
localoverviewupdateConn.Open();
foreach (string single_overview in overviewarray_fromserver)
{
SqlCommand localoverviewupdatecomm = new SqlCommand();
localoverviewupdatecomm.Connection = localoverviewupdateConn;
localoverviewupdatecomm.CommandText = "INSERT INTO overview_keyword (immunity_markers) VALUES(@oimmunity)";
var localoverviewupdateda = new SqlDataAdapter(localoverviewupdatecomm);
localoverviewupdateda.SelectCommand.Parameters.Add(new SqlParameter("@oimmunity", SqlDbType.NVarChar));
localoverviewupdateda.SelectCommand.Parameters["@oimmunity"].Value = single_overview;
var localoverviewupdateds = new DataSet();
localoverviewupdateda.Fill(localoverviewupdateds);
}
localoverviewupdateConn.Close();
}
}
else
{
}
}));
pb_forBasicWaiting.UpdateProgress(100);
}
1 ответ
Вы вообще не ожидаете асинхронную операцию. Это проблема. Правильное использование метода, который не возвращает никакого значения, выглядит следующим образом...
public async Task MethodName()
{
await obj.MethodAsync();
}
Кроме того, если вы используете шаблон асинхронного / ожидающего PTL, вы должны использовать async
, await
везде или иначе использовать ConfigureAwait(false)
где вы можете...