私は良い人のソリューションを採用しました。しかし、私は不確かなものとして使うのが難しいです。まれに、不確定なプログレスバーの回転アニメーションが非常に最近になって表示されます。c#wpf)indeterminateプログレスバーがアニメーションを開始せず、全体的なパフォーマンスをブロックするように見えます。
私は基本的な学習者であり、非同期のbackgroundworker(マルチスレッド)についてはあまり知らないです。だから、私の貧しい知識を親切に許してください。
確定コードと何が違うのですか?私はthis.Dispatcher.BeginInvoke(new Action(async() =>{...}))
を使用しています。なぜなら、bwDoWorkメソッド内のコード待ちのために例外が発生したからです。
私が実装したいのは、メインスレッドとバックグラウンドワーカーが不確定なプログレスバーを一緒にすばやく一緒に表示することで、アプリケーションの実行速度が大幅に向上することです。
誰かが私に相談して、優れた洞察を得ることができます。 progressBar_forBasicWaitingウィンドウの
XAMLコードは、メインウィンドウからコードを開始progressBar_forBasicWaitingウィンドウのCSコードが後ろ
<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>
、
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)
{
}
}
}
は、ある
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コードは、あなたがすべてで非同期操作を待っていない
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);
}
問題の再現に必要なコードを減らし、必要な最小限のコードを入力してください。 – 3615
@ 3615、ok、私はしようとしています。 –
ただの観察。 Dispatcher.BeginInvokeを使用することによって、基本的にはUIスレッドで次のコードを実行するようになります。 load_mainpatientslistdaを満たす操作は、実行されるまでアプリケーションをブロックするUIスレッドで実行されます。 Dispatcher.BeginInvokeはUIと実際にやりとりするコードにのみ使用し、他のコードはすべて並列スレッドで実行する必要があります。 – 3615