[ad_1]
やあ、
私は Dispatcher
プロパティを変更して UI を変更し、追加しました System.Threading.Thread.Sleep(3000)
の Dispatcher.Invoke
フリーズしないようにブロックしますが、UI は 3 秒間フリーズしたままです。
まあ言ってみれば の Dispatcher.Invoke
何らかの理由でブロックに 2 秒かかるため、UI をフリーズさせたくありません。
50ms ルール: 「実行に 50 ミリ秒以上かかる可能性がある」操作は非同期にする必要があります。
上記によると、フリーズせずにWPFのユーザーインターフェイスを変更する最良の方法は何ですか?
これらは私のC#コードです:
private async void Add_Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { await Task.Run(() => { OleDbCommand OleDbCommandInsert = null; MessageWindow MW = null; Dispatcher.Invoke(() => { OleDbParameter Parameter = new OleDbParameter(); Parameter.OleDbType = OleDbType.Binary; Parameter.ParameterName = "BookImage"; Parameter.Value = ImageToBytes((BitmapImage)BookImage.Source); OleDbCommandInsert = new OleDbCommand("Insert Into BookInfo(BookName,Authors,Publisher,[ISBN-13],[ISBN-10],Category,PublicationDate,BookLanguage,Length,[Type],Translators,Narrators,DeweyDecimalClassification,UniversalDecimalClassification,LibraryOfCongressClassification,BookImage,Price) Values(@BookName,@Authors,@Publisher,@ISBN13,@ISBN10,@Category,@PublicationDate,@BookLanguage,@Length,@Type,@Translators,@Narrators,@DeweyDecimalClassification,@UniversalDecimalClassification,@LibraryOfCongressClassification,@BookImage,@Price)", OleDbConnect); OleDbCommandInsert.Parameters.AddWithValue("@BookName", BookName_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Authors", Authors_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Publisher", PublicationDate_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@ISBN13", ISBN13_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@ISBN10", ISBN10_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Category", Category_ComboBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@PublicationDate", PublicationDate_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@BookLanguage", Language_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Length", ushort.Parse(Length_TextBox.Text)); OleDbCommandInsert.Parameters.AddWithValue("@Type", Type_ComboBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Translators", Translators_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Narrators", Narrators_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@DeweyDecimalClassification", DeweyDecimalClassification_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@UniversalDecimalClassification", UniversalDecimalClassification_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@LibraryOfCongressClassification", LibraryOfCongressClassification_TextBox.Text); OleDbCommandInsert.Parameters.Add(Parameter); OleDbCommandInsert.Parameters.AddWithValue("@Price", Price_TextBox.Text); }); OleDbConnect.Open(); OleDbCommandInsert.ExecuteScalar(); OleDbConnect.Close(); Dispatcher.Invoke(() => { MW = new MessageWindow(); System.Threading.Thread.Sleep(3000); MW.YesButton.Visibility = Visibility.Hidden; MW.NoButton.Visibility = Visibility.Hidden; MW.Image.Source = GetImageFromBytes(System.IO.File.ReadAllBytes(System.Windows.Forms.Application.StartupPath + @"\Images\Check.bin")); switch (App.EnumLanguage) { case AllLanguage.English: MW.MessageTextBlock.Text = "Information added successfully"; MW.OKButton.Content = "OK"; break; default: MW.MessageTextBlock.Text = "اطلاعات با موفقیت اضافه شد"; MW.OKButton.Content = "تایید"; break; } MW.Show(); }); }); }
次のツールを使用します。
• .NET フレームワーク 4.5
•WPF
•OLE DB
• Windows 7
お時間をいただきありがとうございます。
メリークリスマス
私が試したこと:
私の一般的なポイントは、 Dispatcher.Invoke
UI の更新に直接関係のないコードを含めないでください。
しかし、時々コードを書かなければなりません Dispatcher.Invoke
.
解決策 1
ディスパッチャーで SQL コマンドを実行するべきではありません。 Dispatcher.Invoke が行うことは、Dispatcher が実行されているスレッドに操作をマーシャリングすることです。したがって、ここで行っていることは、実際には「長時間実行」操作を Dispatcher に強制的に戻すことです。 実際に行う必要があるのは、結果を Dispatcher にマーシャリングすることだけです。
基本的に、UI にマーシャリングする必要があるビットを絞り込み、それらの操作には Dispatcher.Invoke のみを使用します。 したがって、それはコード サンプルのデータベースとは関係ありません。
解決策 2
この特定のケース用のアルゴリズムを作成しました。 わかりやすくするために、次のように説明しました。
クリックしてご覧ください
<Window x:Class="Ganj_Aseman.MessageWindow" x:Name="Message_Window" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Ganj_Aseman" mc:Ignorable="d" Loaded="MessageWindow_Loaded" AllowsTransparency="True" Background="Transparent" FontSize="13" Height="228" RenderTransformOrigin="0.5,0.5" ResizeMode="NoResize" ShowInTaskbar="False" Width="430" WindowStartupLocation="CenterOwner" WindowStyle="None"> <Window.RenderTransform> <TransformGroup> <RotateTransform/> <ScaleTransform/> </TransformGroup> </Window.RenderTransform> <Window.Resources> <Storyboard x:Key="CloseMessageWindow" Storyboard.TargetName="Message_Window" Completed="CloseMessageWindow_Completed"> <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Children[0].Angle" Duration="0:0:7" To="360"/> <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Children[1].ScaleX" Duration="0:0:7" To="0"/> <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Children[1].ScaleY" Duration="0:0:7" To="0"/> <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:7.5" To="0"/> </Storyboard> </Window.Resources> <Grid> <Button Name="OKButton" GotFocus="OKButton_GotFocus" PreviewMouseLeftButtonDown="OKButton_PreviewMouseLeftButtonDown" Content="OK" HorizontalAlignment="Left" VerticalAlignment="Top" Height="34" Margin="177.5,180,0,0"> <Button.Effect> <DropShadowEffect BlurRadius="3" ShadowDepth="0.1" Direction="-90" Color="#e9f1cc"/> </Button.Effect> <Button.Triggers> <EventTrigger RoutedEvent="PreviewMouseLeftButtonDown"> <BeginStoryboard Storyboard="{StaticResource CloseMessageWindow}"/> </EventTrigger> </Button.Triggers> </Button> </Grid> </Window>
private async void Add_Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { await Task.Run(() => { OleDbParameter Parameter = new OleDbParameter(); Parameter.OleDbType = OleDbType.Binary; Parameter.ParameterName = "BookImage"; Dispatcher.Invoke(() => { Parameter.Value = ImageToBytes((BitmapImage)BookImage.Source); }); OleDbCommand OleDbCommandInsert = new OleDbCommand("Insert Into BookInfo(BookName,Authors,Publisher,[ISBN-13],[ISBN-10],Category,PublicationDate,BookLanguage,Length,[Type],Translators,Narrators,DeweyDecimalClassification,UniversalDecimalClassification,LibraryOfCongressClassification,BookImage,Price) Values(@BookName,@Authors,@Publisher,@ISBN13,@ISBN10,@Category,@PublicationDate,@BookLanguage,@Length,@Type,@Translators,@Narrators,@DeweyDecimalClassification,@UniversalDecimalClassification,@LibraryOfCongressClassification,@BookImage,@Price)", OleDbConnect); Dispatcher.Invoke(() => { OleDbCommandInsert.Parameters.AddWithValue("@BookName", BookName_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Authors", Authors_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Publisher", PublicationDate_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@ISBN13", ISBN13_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@ISBN10", ISBN10_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Category", Category_ComboBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@PublicationDate", PublicationDate_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@BookLanguage", Language_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Length", ushort.Parse(Length_TextBox.Text)); OleDbCommandInsert.Parameters.AddWithValue("@Type", Type_ComboBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Translators", Translators_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@Narrators", Narrators_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@DeweyDecimalClassification", DeweyDecimalClassification_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@UniversalDecimalClassification", UniversalDecimalClassification_TextBox.Text); OleDbCommandInsert.Parameters.AddWithValue("@LibraryOfCongressClassification", LibraryOfCongressClassification_TextBox.Text); OleDbCommandInsert.Parameters.Add(Parameter); OleDbCommandInsert.Parameters.AddWithValue("@Price", Price_TextBox.Text); }); OleDbConnect.Open(); OleDbCommandInsert.ExecuteScalar(); OleDbConnect.Close(); Dispatcher.Invoke(() => { MessageWindow MW = new MessageWindow(); MW.Owner = this; MW.Owner.IsEnabled = false; MW.YesButton.Visibility = Visibility.Hidden; MW.NoButton.Visibility = Visibility.Hidden; MW.Image.Source = GetImageFromBytes(System.IO.File.ReadAllBytes(System.Windows.Forms.Application.StartupPath + @"\Images\Check.bin")); switch (App.EnumLanguage) { case AllLanguage.English: MW.MessageTextBlock.Text = "Information added successfully"; MW.OKButton.Content = "OK"; break; default: MW.MessageTextBlock.Text = "اطلاعات با موفقیت اضافه شد"; MW.OKButton.Content = "تایید"; break; } MW.Show(); }); }); }
private void OKButton_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.Owner.IsEnabled = true; } private void CloseMessageWindow_Completed(object sender, EventArgs e) { Close(); }
結果(私は Duration
のプロパティ Animation
結果をよりよく理解するために 7 秒まで):
クリックしてご覧ください
[ad_2]
コメント