Skip to content

Any chance of command queueing instead of dropping? #685

@ACher91

Description

@ACher91

I just got done troubleshooting a massive bug that really threw a wrench in my project. I updated from version 4.1 to 7 yesterday, and it created a new issue that wasn't there before: when switching between files, sometimes audio files are just not loaded. After (way too) many hours of debugging, I finally found the culprit: CommandManager.Direct's ExecuteDirectCommand method. Towards the start, it does this:

if (IsDirectCommandPending || command == DirectCommandType.None)
{
    this.LogWarning(Aspects.EngineCommand, $"Direct Command '{command}' not accepted. {PendingDirectCommand} command is pending completion.");
    return Task.FromResult(false);
}

If a command is still pending, in this case the close command from a video file, the open command to open the next audio file will just be eaten here. Part of what made debugging this so difficult is that the MediaElement.MediaOpening, MediaElement.MediaOpened, and MediaElement.MediaFailed events aren't even set up to fire at this point, so there is zero feedback as to what is going wrong. I was quite shocked to find that this isn't something that existed back in version 4.1.

Before, there used to be crash bugs that came out of switching between files too fast, and it seems like those have all been eradicated, but in doing so, the new files just can't be switched to at all. Well, that's... one way to do it I guess. 🙃 I appreciate the increased thread safety, but why must it come at the expense of common UI functionality? Surely there's a way to get the best of both worlds? I feel like the version 7 implementation is a fundamentally unsafe choice for an async API that lives in real-time UI environments, where users or viewmodels often issue commands before previous ones have finished.

For the time being, I've modified that bit to solve my problem:

if (IsDirectCommandPending || command == DirectCommandType.None)
{
    return Task.Run(async () =>
    {
        while (IsDirectCommandPending)
            await Task.Delay(10);
        return await ExecuteDirectCommand(command, commandDelegate);
    });
}

This seems to have worked well enough, but I obviously don't know the code base like you guys, so not sure if this could cause other problems. It's a bit of a janky solution at best, I suppose.

So uhh, yeah.... any chance of getting some type of official support for a queueing system here, instead of just silently swallowing the commands if they're input too quickly?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions