2015-09-27 1 views
7

を実行している場合は、バックグラウンドタスクを停止?アプリケーション用のユニバーサルWindowsプラットフォームを使用しています。のWindows 10 UWP - フォアグラウンドアプリが実行されているフォアグラウンドのアプリがある場合は、私が実行してから、バックグラウンドタスクを防ぐことができますどのように

私のバックグラウンドタスクは、いくつかのサイトに新しいアイテムをチェックし、利用可能な新しいものがあるトーストを送信しますが、私は、ユーザーが今のアプリケーションを実行している場合、送信トーストを防ぐためにwan'tています。

アプリケーションの起動時にタスクの登録を解除し、アプリケーションが終了したときに再び登録しようとしましたが、これは私にとっては解決策ではありません。何らかの理由でデバイスがシャットダウンしたとき(バッテリが取り外されたなど)タスクはアプリが再び起動されるまで登録されません。

ありがとうございました。

+1

ソリューションを見つけましたか?アプリケーショントリガータスクを使用していますか? – peterincumbria

答えて

0

私は非常に簡単な解決方法を知りたいです。それを避けて、仲裁の仕組みを整えることができます。これらの線に沿って何か:メインアプリで

public class AppSynchronization 
{ 
    // Called by the main app on launch or on resume. It will signal the main app's intention to start. 
    // The main app will not perform any significant actions before this method returns. 
    public void ActivateMainApp() {...} 

    // Called by the main app. It will signal the fact that the main app is "going away". 
    public async Task MainAppSuspended() {...} 

    // Called by the background agent. 
    // It will signal the background agent intention to start. 
    // This method will only return if the main app is out of the way. 
    // It will return a cancellation token that will be used to cancel the activity of the background agent when the main app advertises its intention to start. 
    public async Task<CancellationToken> ActivateBackgroundAgent(CancellationToken cancelWait) 
    { 
     // Make sure the main app is not started or wait until the main app is out of the way 

     // Start a thread that is on the lookout for the main app announcing that it wants to start. 
     // When that happens it will cancel the cancellation token returned. 
    } 

    // <summary> 
    // Called by the background agent. 
    // It will signal the fact that the background agent completed its actions. 
    public async Task DeactivateBackgroundAgent() 
} 

private AppSynchronization appSynchronization; 

public App() 
{ 
    ... 
    this.appSynchronization = new AppSynchronization(); 
} 

protected async override void OnLaunched(LaunchActivatedEventArgs e) 
{ 
    ... 
    if (rootFrame.Content == null) 
    { 
     // Advertise the fact that the main app wants to start. 
     // The background agent will know to cancel whatever its doing. 
     // ActivateMainApp may have to be async although you need to make sure that OnLaunched supports that 
     this.appSynchronization.ActivateMainApp(); 
     ... 
    } 
} 

private async void OnResuming(object sender, object e) 
{ 
    ... 
    // Advertise the fact that the main app wants to resume. 
    // The background agent will know to cancel whatever its doing. 
    this.appSynchronization.ActivateMainApp(); 
} 


private async void OnSuspending(object sender, SuspendingEventArgs e) 
{ 
    var deferral = e.SuspendingOperation.GetDeferral(); 

    ... 
    // Advertise the fact that the main app is suspending. 
    // The background agent will know it is allowed to start doing work. 
    await _mainAppSynchronization.MainAppSuspended(); 

    ... 
    deferral.Complete(); 
} 

private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) 
{ 
    ... 
    // Advertise the fact that the main app is going away. 
    // The background agent will know it is allowed to start doing work. 
    _mainAppSynchronization.MainAppSuspended().Wait(); 
} 

、バックグラウンドエージェントで:

public sealed class BackgroundTask : IBackgroundTask 
{ 
    public async void Run(IBackgroundTaskInstance taskInstance) 
    { 
     ... 
     AppSynchronization appSynchronization = new AppSynchronization(); 
     BackgroundTaskDeferral deferral = taskInstance.GetDeferral(); 

     // Make sure that the main app is not started. If it is started then wait until the main app gets out of the way. 
     // It he main app is running this will wait indefinitely. 
     // Use backgroundAgentCancellationToken to cancel the actions of the background agent when the main app advertises its intention to start. 
     CancellationToken backgroundAgentCancellationToken = await appSynchronization.ActivateBackgroundAgent(); 

     await DoBackgroundAgentWork(backgroundAgentCancellationToken) 

     // Advertise the fact that the background agent is out. 
     // DeactivateBackgroundAgent will make sure that the synchronization mechanism advertised the fact that the background agent is out. 
     // DeactivateBackgroundAgent may have to be declared async in case the synchronization mechanism uses async code to do what is needed. 
     await appSynchronization.DeactivateBackgroundAgent(); 

     deferral.Complete(); 
    } 

私はプロセス間で通信するために、どのような方法があるかどうかわかりませんUWPで調停メカニズム自体は、ローカルストレージ上のファイルに基づいている必要があります。

調停機構は、一つ又は他のプロセスが壊滅的な方法でクラッシュした場合に、ハートビート機構を含むように有することができます。

+0

"メインアプリを実行している場合、これは無期限に待機します。" (bgタスクで)。あなたはこれについて確信を持っていますか?実行時間が長すぎるとバックグラウンドタスクが終了しないのですか?または、待機はCPU使用率としてカウントされませんか?可能であれば、いくつかの洞察を得たいと思う。ありがとう:) – sibbl

+0

ActivateBackgroundAgentで実装されたアービトレーションメカニズムが数秒間スリープするループを持っている場合、メインアプリケーションの状態をチェックします(メインアプリケーションが作成しているファイルの存在を調べることによって)非常に少ない。睡眠時間はカウントされません。最終的にバックグラウンドエージェントが中断され、OSが再開するまで何時間も待たなければなりません。あなたはこれの周りに多くのテストを行う必要があります。私の知る限り、Windows 8.1対WP 8.1のバックグラウンドエージェントには重要な違いがありました。 UWPについては不明。 – Ladi

+0

DeviceUseTriggerがトリガでない場合、UWPでは、アプリケーショントリガの場合、バックグラウンドタスクは10分後にキャンセルされます。これは、SensorCoreが廃止されて以来、GPS追跡アプリケーションで本当に苦痛を与えています。 – peterincumbria

1

は、私がTimeTriggerによってトリガーされBackgroundTaskのを持ってフォアグラウンドアプリやバックグラウンドエージェント

0

間で同期するという名前のミューテックスを使用してください。そのタスクは、アプリを最初にロードする必要なしに、電話の再起動後に自動的に再開します。たぶんそれはあなたがコード

var value = ApplicationSettingsHelper.ReadResetSettingsValue(ApplicationSettingsConstants.AppState); 
if (value == null) 
    foregroundAppState = AppState.Unknown; 
else 
    foregroundAppState = EnumHelper.Parse<AppState>(value.ToString()); 

if (foregroundAppState == AppState.Suspended) 
     //Do something 
else if (foregroundAppState == AppState.Active) 
     return; 
else if (foregroundAppState == AppState.Unknown) 
     return; 
0

を[編集済み] ...

に役立つだろうアプリケーションのローカル設定を使用することです。

フォアグラウンドとバックグラウンドで設定を変更します。 フォアグラウンドの例としてこれを行います。

/// <summary> 
/// When the window visibility changes 
/// </summary> 
/// <param name="sender">object sender</param> 
/// <param name="e">VisibilityChangedEventArgs e</param> 
private void OnVisibilityChanged(object sender, VisibilityChangedEventArgs e) 
{ 
    var localSettings = ApplicationData.Current.LocalSettings; 

    if (!e.Visible) 
    { 
     localSettings.Values["AppInForeground"] = false;    
    } 
    else 
    { 
     localSettings.Values["AppInForeground"] = true; 
    } 
} 

、あなたのバックグラウンドタスクは、10分後にキャンセルされますDeviceUseTriggerを使用していない場合は残念ながらsibbiは、正しいです。

0

の下に使用してアプリケーションの状態を確認することができます...ちょうど実現私は私の答えで遅刻だ

0

これは、この質問に似ている:あなたはアプリがあるかどうかを確認することができ、インプロセスタスクにhttps://docs.microsoft.com/en-us/windows/uwp/launch-resume/convert-out-of-process-background-task

:インプロセスのバックグラウンドタスクにタスクを変換することですHow to stop the background task if the app is starting?

最も簡単な方法フォアグラウンドで、またはバックグラウンドアクティビティから直接ではありません。

あなたがメインのアプリから別のプロセスのように、あなたのバックグラウンドタスクを維持する必要がある場合は、次のいずれかを行うことができます

  • ファイルを経由してミューテックスを作成します。
  • In-procアプリサービスを作成し、バックグラウンドタスクから通信しようとします。次に、アプリケーションがフォアグラウンドにあるかどうかを返すことができます。
  • アプリローカル設定辞書を使用して、フォアグラウンドアプリが実行されているかどうかのフラグを保持します。アプリのクラッシュによってフラグが正しくリセットされない可能性があるため、これは最も脆弱です。
関連する問題