Windows 10 UWP - 如果前台应用程序正在运行,则停止后台任务

Vla*_*iev 8 c# windows windows-phone background-task uwp

如果正在执行前台应用程序,如何阻止后台任务运行?为我的应用程序使用通用Windows平台.

我的后台任务是检查某个站点上的新项目,并在有新的东西时发送一个Toast,但是如果用户现在正在运行应用程序,我不想阻止吐司发送.

我试图在我的应用程序启动时取消注册任务并在应用程序终止时再次注册,通过,这对我来说不是很好的解决方案 - 当设备由于某种原因关闭时(例如,电池被移除)我的任务将不会注册,直到应用再次启动

谢谢.

Lad*_*adi 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()
 }
Run Code Online (Sandbox Code Playgroud)

在主应用程序中:

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();
}
Run Code Online (Sandbox Code Playgroud)

并在后台代理中:

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();
    }
Run Code Online (Sandbox Code Playgroud)

我不确定UWP中是否有任何方法可以跨进程通信。仲裁机制本身可能必须基于本地存储上的文件。

仲裁机制可能必须包括心跳机制,以防一个或另一个进程以灾难性方式崩溃。