2

我有一个无头 UWP 应用程序,它使用外部库连接到串行设备并发送一些命令。它运行一个无限循环(如果为真),循环之间有 10 分钟的暂停。测量过程大约需要 4 分钟。外部库需要运行 3 次测量,并在每次测量后通过引发事件发出信号。当第四次引发事件时,我知道我可以返回结果。

4 小时(+/- 几秒)后,库停止引发事件(通常它引发事件一到两次,然后停止,没有错误,什么都没有)。

我在 DoMeasureAsync() 下面实现了一个 CancellationTokenSource,它应该在 8 分钟后在 TaskCompletionSource 上设置 IsCancelled 属性,以便任务返回并继续循环。

问题:当测量未完成时(NMeasureCompletionSource 永远不会在类 CMeasure 中获得其结果集),来自 nMeasureCompletionSource 的任务永远不会取消。RespondToCancellationAsync() 中定义的委托应在 8 分钟后运行。

如果测量运行正常,我可以在日志中看到

taskAtHand.ContinueWith((x) =>

        {
            Logger.LogDebug("Disposing CancellationTokenSource...");
            cancellationTokenSource.Dispose();
        });

被调用。

编辑GC 是否有可能在 4 小时后进入,并且可能会释放一些变量,这样做会使应用程序无法将命令发送到传感器?- 事实并非如此

我在这里想念什么?

 //this gets called in a while (true) loop
    public Task<PMeasurement> DoMeasureAsync()
    {

        nMeasureCompletionSource = new TaskCompletionSource<PMeasurement>();

        cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(8));

        var t = cMeasure.Run(nitrateMeasureCompletionSource, cancellationTokenSource.Token);

        var taskAtHand = nitrateMeasureCompletionSource.Task;
        taskAtHand.ContinueWith((x) =>

        {
            Logger.LogDebug("Disposing CancellationTokenSource...");
            cancellationTokenSource.Dispose();
        });

        return taskAtHand;
    }

    public class CMeasure
    {
        public async Task Run(TaskCompletionSource<PMeasurement> tcs, CancellationToken cancellationToken)
        {
            try
            {
                NMeasureCompletionSource = tcs;
                CancellationToken = cancellationToken;

                CancellationToken.Register(async () => await RespondToCancellationAsync(), useSynchronizationContext: false);

                CloseDevice(); //Closing device if for some reason is still open
                await Task.Delay(2500);

                TheDevice = await GetDevice();

                measurementsdone = 0;

                Process(); //start the first measurement
            }
            catch (Exception ex)
            {
                DisconnectCommManagerAndCloseDevice();

                NMeasureCompletionSource.SetException(ex);
            }
        }

        public async Task RespondToCancellationAsync()
        {

            if (!NitrateMeasureCompletionSource.Task.IsCompleted)
            {
                Logger.LogDebug("Measure Completion Source is not completed. Cancelling...");
                NMeasureCompletionSource.SetCanceled();
            }

            DisconnectCommManagerAndCloseDevice();

            await Task.Delay(2500);

        }

        private void Process()
        {

            if (measurementsdone < 3)
            {
                var message = Comm.Measure(m); //start a new measurement on the device
            }
            else
            {
                ...
                NMeasureCompletionSource.SetResult(result);
            }

        }

        //the method called when the event is raised by the external library
        private void Comm_EndMeasurement(object sender, EventArgs e)
        {
            measurementsdone++;

            Process();
        }
    }
4

1 回答 1

1

经过更多的测试,我得出的结论是没有内存泄漏并且所有对象都已被释放。取消也很有效。

到目前为止,我的问题似乎来自于在 Raspberry Pi 上执行无头应用程序。虽然我使用的是 deferral = taskInstance.GetDeferral(); 似乎执行在某个时候停止了......

我将进行更多测试并返回结果(可能在新帖子中,但我也会在此处放置链接)。

编辑:这是新帖子:UWP - Headless app 在 3 或 4 小时后停止

编辑 2: 问题来自我必须使用的第 3 方库,并且它的调用方式必须与无头应用程序不同。如果 SynchronizationContext.Current 为空,它在内部创建自己的 TaskScheduler。

于 2017-08-17T08:46:26.293 回答