.net 3.5 SP1でスプラッシュスクリーンを作成する

.netでプログラミングに出くわした場合、WPFを使用して作成されたプログラムを起動したときに、何も長い間何も起こらないことに気づいたと思います。 これは10秒間続き、その後、メインアプリケーションウィンドウが開きます。 空のWPFアプリケーションテンプレートを起動する場合でも、約2秒かかります。

この一時停止は、プログラムのユーザーの認識に不確実性をもたらします。プログラムが開始されたかどうか。

この問題は、起動直後にスプラッシュ画面を表示することで解決できます。 これにより、アプリケーションの起動直後に物理的な応答が得られ、ロードが高速化されたように見えます。

これを行う方法は、カットの下に書かれています。

アプリケーションのロードが長いのはなぜですか



これは、約20メガバイトを占める.netライブラリがWindowsの起動時にメモリにロードされないためです。 .net Frameworkは、プログラムの起動時に必要なライブラリを動的にロードします。 プログラムの開始時にスタジオでOutputを見ると、次のことがわかります。

「SplashDemo.vshost.exe」(管理対象):「C:\ Windows \ assembly \ GAC_32 \ mscorlib \ 2.0.0.0__b77a5c561934e089 \ mscorlib.dll」が読み込まれ、シンボルの読み込みがスキップされました。 モジュールが最適化され、デバッガーオプション「Just My Code」が有効になります。
「SplashDemo.vshost.exe」(管理対象):「C:\ Windows \ assembly \ GAC_MSIL \ Microsoft.VisualStudio.HostingProcess.Utilities \ 9.0.0.0__b03f5f7f11d50a3a \ Microsoft.VisualStudio.HostingProcess.Utilities.dll」を読み込み、シンボルの読み込みをスキップしました。 モジュールが最適化され、デバッガーオプション「Just My Code」が有効になります。
「SplashDemo.vshost.exe」(管理対象):「C:\ Windows \ assembly \ GAC_MSIL \ PresentationFramework \ 3.0.0.0__31bf3856ad364e35 \ PresentationFramework.dll」をロードし、シンボルのロードをスキップしました。 モジュールが最適化され、デバッガーオプション「Just My Code」が有効になります。
...
...
...
'SplashDemo.vshost.exe'(管理対象):ロード済み 'D:\ work \ Visual Studio 2008 \ Projects \ SplashDemo \ bin \ Debug \ SplashDemo.exe'、ロードされたシンボル。
ステップイン:非ユーザーコード「System.Windows.SplashScreen.SplashScreen」のステップオーバー
ステップイン:非ユーザーコード「SplashDemo.App.App」のステップオーバー
「SplashDemo.vshost.exe」(管理対象):「C:\ Windows \ assembly \ GAC_MSIL \ System.Configuration \ 2.0.0.0__b03f5f7f11d50a3a \ System.Configuration.dll」をロードし、シンボルのロードをスキップしました。 モジュールが最適化され、デバッガーオプション「Just My Code」が有効になります。
ステップイン:非ユーザーコード「SplashDemo.App.InitializeComponent」をステップオーバーする
「SplashDemo.vshost.exe」(管理対象):「C:\ Windows \ assembly \ GAC_MSIL \ PresentationFramework.Aero \ 3.0.0.0__31bf3856ad364e35 \ PresentationFramework.Aero.dll」を読み込み、シンボルの読み込みをスキップしました。 モジュールが最適化され、デバッガーオプション「Just My Code」が有効になります。


以前の決定方法



アプリケーションを開始する前に、タンバリンと踊り、ネイティブコードを実行する必要がありました。 そして何とか彼を止めます。 Quicksplash商用コンポーネントは、アプリケーションをロードした後、指定されたフォルダーからファイルを削除することを提案します。 このオプションはやや不便です。 残りはさらに悪い。

今どのように解決されますか



.net 3.5 sp1の登場により、わずか2クリックですべてが完了します。 次の形式の画像のみがサポートされています:BMP、GIF、JPEG、PNGおよびTIFF。 PNGはアルファチャネルをサポートしています。

オプション番号1



最も簡単なオプション。 99%のケースで十分です。 スクリーンセーバーを作成するには、プロジェクトに画像を追加する必要があります。



追加したファイルの[ プロパティ]ウィンドウで、[ ビルドアクション]パラメーターをSplashScreenに設定します。



必要なのはそれだけです。

ビルド時に、次の行がApp.g.csファイルに追加されます。

SplashScreen splashScreen = new SplashScreen( "splash.png" );
splashScreen.Show( true );

* This source code was highlighted with Source Code Highlighter .


後で分析します。

オプション番号2a



2番目のオプションは最初のオプションと大差ありません。自分で行うだけです。 これを行うには、プロジェクトに画像を追加します。 App.xamlApp.xaml.csではなく)を開き、StartUpイベントの新しいハンドラーを追加します。



App.xaml.csファイルに移動して、新しく作成されたメソッドを探し、次の行で追加します。

private void AppStartUp( object sender, StartupEventArgs e)
{
var splash = new SplashScreen( "splash.png" );
splash.Show( true );
}


* This source code was highlighted with Source Code Highlighter .


それらを分解してみましょう。 最初の行は、SplashScreenクラスの新しいインスタンスを作成します。 コンストラクターには単一のパラメーターがあります-ファイル名:

var splash = new SplashScreen( "splash.png" );

* This source code was highlighted with Source Code Highlighter .


2行目では、 Showメソッド(bool autoClose)を呼び出します。 引数の値がtrueの場合、アプリケーションをロードした後、スプラッシュ画面が自動的に閉じます。 それ以外の場合は、 Closeメソッドを呼び出す必要があります

splash.Show( true );

* This source code was highlighted with Source Code Highlighter .


オプション番号2b



実践では、起動時だけでなく、たとえば認証ウィンドウの直後にスプラッシュスクリーンを表示する必要がある場合があることが示されています。

public Window1()
{
ShowAuthorizationDialog();

InitializeComponent();
}


* This source code was highlighted with Source Code Highlighter .


InitializeComponent()は認証後に呼び出されるため、メインアプリケーションのコードで使用されるライブラリの追加の読み込みがありますが、認証ウィンドウでは使用されません。 これにより、メインウィンドウが表示される前に遅延が発生します。 この影響を回避するには、次のことを実行できます。

public Window1()
{
ShowAuthorizationDialog();

var splash = new SplashScreen( "spalsh.png" );
splash.Show( false );

InitializeComponent();

splash.Close( TimeSpan .FromMinutes(0.5));
}


* This source code was highlighted with Source Code Highlighter .


以下が唯一の新しい行です。

splash.Close( TimeSpan .FromMinutes(0.5));

* This source code was highlighted with Source Code Highlighter .


Close()メソッドは、スプラッシュスクリーンをフェード効果で閉じます。 パラメータとして、メソッドはスクリーンセーバーが「外出」する時間間隔をとります。

既知のバグ



使用の過程で、透明ではなく黒い背景が数回滑りました。 理由はまだ特定されていません。

Win32Exeptionは、スクリーンセーバーが消えたときに別のアプリケーションに切り替えるときに発生します。 Close()メソッドをtry ... catchブロックで囲むことでキャッチできます

おわりに



プログラムでスクリーンセーバーを使用すると、ユーザーに対してより快適で人道的になります。 開発者に対する不必要な精神的攻撃を避けることができます。 :-)

UPD:これは、WPFアプリケーションにのみ適用されます。
UPD2: .NETブログに移動しました。 ありがとう

Source: https://habr.com/ru/post/J45459/


All Articles