.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.xaml (
App.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ブログに移動しました。 ありがとう