如何在 UWP 后台应用程序中同时执行 2 个任务 运行?

How to make 2 tasks run simultaneously in a UWP background app?

我需要帮助 运行在我的 Raspberry Pi 上部署我的 UWP 后台应用程序(托管 Windows 10 IOT Core)。

它几乎可以工作,但我遇到了一个棘手的问题...让我解释一下:

该应用程序有 2 个功能:

如果单独执行,这两个功能都能很好地工作,但我需要它们同时 运行。我是 UWP 和 Raspberry 的新手,所以也许我遗漏了什么......

我很难将项目分成两个独立的可部署任务,我相信它会起作用,但我需要网络服务器任务来控制 (START/PAUSE/STOP) 重复任务。

我认为它们之间的通信是可行的(使用 this way),但我正在寻找 simplest/fastest 解决方案。

这是精简代码(3 classes 在单独的文件中):

应用class:

public sealed class StartupTask : IBackgroundTask
{
    private static BackgroundTaskDeferral _Deferral = null;

    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        _Deferral = taskInstance.GetDeferral();

        var webserver = new WebServer();
        await ThreadPool.RunAsync(workItem => { webserver.Start(); });

        StartRepeatingTask();
    }
}

网络服务器class:

internal class WebServer
{
    private const uint BUFFER_SIZE = 8192;

    public async void Start()
    {
        var listener = new StreamSocketListener();
        await listener.BindServiceNameAsync("1537");

        listener.ConnectionReceived += async (sender, args) =>
        {
            // Do some stuff
            ...
            Processing.StopProcess();
        }
    }
}

处理中class

public class Processing 
{
    private static Task myTask = null;
    private static CancellationTokenSource taskCancellation = new CancellationTokenSource();

    public static void StartRepeatingTask()
    {
        taskCancellation = new CancellationTokenSource();
        myTask = Task.Run(() => AutoProcess(), taskCancellation.Token);
    }

    public static void AutoProcess()
    {
        Process();

        myTask = Task.Delay(GetDelayToUse(DELAY_SET_LIST))
            .ContinueWith(t => AutoProcess(), taskCancellation.Token);
    }

    public static void Process()
    {
        // Do some other stuff
    }

    public static void StopProcess()
    {
        taskCancellation.Cancel();
    }
}

这两个任务可以在后台应用程序中同时 运行。

Is it a matter of thread conflict?

如果两个任务之间没有提交或共享数据,则不会发生冲突。重要的是你需要注意数据的同步。如果使用列表或队列在两个线程之间共享数据,则应使用并发对象。请参考ConcurrentQueue例子,ConcurrentQueue代表线程安全。

Is a background task on a raspberry limited to a single thread (so the first/last process executed wins)?

部署和配置后台应用程序后,这些应用程序会在机器启动时启动,并且 运行 持续运行,没有任何进程生命周期管理资源使用限制。后台任务有一些限制,但不限于单线程。有关 Windows IoT Core 和任务的更多信息 here. Here you need to differentiate the background application

Do all classes need to be "sealed" (microsofts's doc says so but not the example they provide)?

是的,后台任务 class 本身——以及后台任务项目中的所有其他 classes——需要被 public class 密封(或最终)。它适用于继承自接口 IBackgroundTask 的后台任务,但不适用于 classes 用于普通线程。