2016-08-10 5 views
1

コンピュータの起動時に実行する短いC#スクリプトを書きました。その機能はiTunesを監視し、私が聴いているアーティストを示すSkypeのステータスとして楽しいメッセージを表示することです。メモリを食らわずに連続したWindowsのバックグラウンドタスクを実行

iTunesAppオブジェクトを作成し、トラックがいつ変更されるかを検出するリスナーを追加します。問題は、私のアプリをバックグラウンドで開いたままにするためにwhile(true)ループを使用する必要があるか、そうでなければ実行して終了するということです。タスクマネージャーを見て、この小さなプログラムがCPUの15〜20%を使用していることを認識するまで、これは大丈夫だと思いました!

良いアプローチがありますか?

static void Main(string[] args) 
{ 
    iTunesApp = new iTunesAppClass(); 
    iTunesApp.OnPlayerPlayEvent += ITunesApp_OnPlayerPlayEvent; 
    while (true) 
    { } 
} 

private static void ITunesApp_OnPlayerPlayEvent(object iTrack) 
{ 
    var currentArtist = iTunesApp.CurrentTrack.Artist; 
    if (currentArtist != LastArtist) 
    { 
     LastArtist = currentArtist; 
     var message = GetMessage(currentArtist); 
     UpdateSkypeStatus(message); 
     UpdateLog(message); 
    } 
} 

完全なプロジェクトがhttps://github.com/ericsundquist/SkypeTunesである:ここでは

のアイデアを得るために、コードの心臓部です。

+2

Application.Run(); –

+0

while(true)ループがあり、CPUの解放はありません。右の解決策ではありませんが、そのループ内にThread.sleep()コールを追加することができます。そして、正しい方法で実行できるようになるまで、少なくともCPUを解放します。 – ManoDestra

+0

[Application.Run](https://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx)。 – IInspectable

答えて

3

ManualResetEventで待機し、プログラムを終了する必要があるときに設定します。私の例では、プログラムを終了するためにStopを呼び出します。

static ManualResetEvent signal; 
static void Main(string[] args) 
{ 
    iTunesApp = new iTunesAppClass(); 
    iTunesApp.OnPlayerPlayEvent += ITunesApp_OnPlayerPlayEvent; 

    signal = new ManualResetEvent(false); 
    signal .WaitOne(); 
} 

public static void Stop() 
{ 
    signal.Set(); 
} 

private static void ITunesApp_OnPlayerPlayEvent(object iTrack) 
{ 

    var currentArtist = iTunesApp.CurrentTrack.Artist; 
    if (currentArtist != LastArtist) 
    { 
     LastArtist = currentArtist; 
     var message = GetMessage(currentArtist); 
     UpdateSkypeStatus(message); 
     UpdateLog(message); 
    } 
} 
+0

これは、コメント提案のApplication.Run()よりも優れています(ただし、これも有効です)。処理されるウィンドウイベントはないので、コンソールアプリケーションを開いたままにするためにメッセージループをポンピングするのは無関係です。 'Console.WriteLine("終了するには任意のキーを押してください。 "); Console.ReadKey(); 'も働くだろう。 –

+0

@EricJ .: * "メッセージループをポンプするのは無関係です" * - それ以外は 'Application.Run'とは異なります。 'GetMessage'を深く呼びます。これは、メッセージがあるまで、決して返されないブロッキング呼び出しです。あなたが意味するような方法でリソースを無駄にすることはありません。 – IInspectable

+0

@IInspectable:コンソール(およびWindowsサービス)アプリケーションは、通常、正しく機能するためにGetMessageを呼び出す必要はありません。リソースを無駄にするわけではありませんが(私はそのことを暗示するつもりはありませんでしたが)それは無関係です(私が言ったことです)。 –

関連する問題