Example #1
0
        /// <summary>
        /// Calls the execution of the given command instance
        /// and wait for its completion without blocking the dispatcher
        /// </summary>
        /// <param name="command">The command.</param>
        private void ExecuteAndWaitFor(MediaCommand command)
        {
            var executeTask = Task.Run(() =>
            {
                if (command.HasCompleted)
                {
                    return;
                }
                command.Execute();
            });

            var waitTask = Task.Run(async() =>
            {
                while (command.HasCompleted == false)
                {
                    await Task.Delay(10);
                }
            });

            while (waitTask.IsCompleted == false)
            {
                // Pump invoke
                Dispatcher.CurrentDispatcher.Invoke(
                    DispatcherPriority.Background,
                    new Action(() => { }));
            }
        }
        /// <summary>
        /// Opens the specified URI.
        /// The command is processed in a Thread Pool Thread.
        /// </summary>
        /// <param name="uri">The URI.</param>
        /// <returns>The awaitable Open operation</returns>
        public DispatcherOperation Open(Uri uri)
        {
            // Check Uri Argument
            if (uri == null)
            {
                MediaElement?.Logger.Log(
                    MediaLogMessageType.Warning,
                    $"{nameof(MediaCommandManager)}.{nameof(Open)}: '{nameof(uri)}' cannot be null");

                return(Dispatcher.CurrentDispatcher.CreatePumpOperation());
            }

            if (CanExecuteCommands == false)
            {
                return(Dispatcher.CurrentDispatcher.CreatePumpOperation());
            }
            else
            {
                IsOpening.Value = true;
            }

            var command = new OpenCommand(this, uri);

            ExecutingCommand = command;
            ClearCommandQueue();

            var backgroundTask = Task.Run(() =>
            {
                try
                {
                    if (command.HasCompleted)
                    {
                        return;
                    }
                    command.Execute();
                }
                catch (Exception ex)
                {
                    MediaElement?.Logger.Log(
                        MediaLogMessageType.Error,
                        $"{nameof(MediaCommandManager)}.{nameof(Open)}: {ex.GetType()} - {ex.Message}");
                }
                finally
                {
                    ExecutingCommand?.Complete();
                    ExecutingCommand = null;
                    IsOpening.Value  = false;
                }

                System.Diagnostics.Debug.Assert(
                    MediaElement.IsOpen == true && MediaElement.IsOpening == false && command.HasCompleted,
                    "Synchronous conditions not met");
            });

            var operation = Dispatcher.CurrentDispatcher.CreateAsynchronousPumpWaiter(backgroundTask);

            return(operation);
        }
        /// <summary>
        /// Enqueues the command for execution.
        /// </summary>
        /// <param name="command">The command.</param>
        private void EnqueueCommand(MediaCommand command)
        {
            if (MediaCore.IsOpen == false)
            {
                command.Complete();
                return;
            }

            lock (SyncLock)
                Commands.Add(command);
        }
        /// <summary>
        /// Opens the specified URI.
        /// This command gets processed in a threadpool thread asynchronously.
        /// </summary>
        /// <param name="uri">The URI.</param>
        /// <returns>The asynchronous task</returns>
        public async Task OpenAsync(Uri uri)
        {
            // Check Uri Argument
            if (uri == null)
            {
                MediaCore?.Log(
                    MediaLogMessageType.Warning,
                    $"{nameof(MediaCommandManager)}.{nameof(OpenAsync)}: '{nameof(uri)}' cannot be null");

                return; // Task.CompletedTask;
            }

            if (CanExecuteCommands == false)
            {
                return; // Task.CompletedTask;
            }
            else
            {
                IsOpening.Value = true;
            }

            var command = new OpenCommand(this, uri);

            ExecutingCommand = command;
            ClearCommandQueue();

            var action = new Action(() =>
            {
                try
                {
                    if (command.HasCompleted)
                    {
                        return;
                    }
                    command.RunSynchronously();
                }
                catch (Exception ex)
                {
                    MediaCore?.Log(
                        MediaLogMessageType.Error,
                        $"{nameof(MediaCommandManager)}.{nameof(OpenAsync)}: {ex.GetType()} - {ex.Message}");
                }
                finally
                {
                    ExecutingCommand?.Complete();
                    ExecutingCommand = null;
                    IsOpening.Value  = false;
                }
            });

            await TaskEx.Run(action);
        }
        /// <summary>
        /// Processes the next command in the command queue.
        /// This method is called in every block rendering cycle.
        /// </summary>
        public async Task ProcessNext()
        {
            MediaCommand command = null;

            lock (SyncLock)
            {
                if (Commands.Count == 0) return;
                command = Commands[0];
                Commands.RemoveAt(0);
            }

            await command.ExecuteAsync();
        }
        /// <summary>
        /// Opens the specified custom input stream.
        /// This command gets processed in a threadpool thread asynchronously.
        /// </summary>
        /// <param name="stream">The custom input stream.</param>
        /// <returns>
        /// The asynchronous task
        /// </returns>
        public async Task OpenAsync(IMediaInputStream stream)
        {
            // Check Uri Argument
            if (stream == null)
            {
                MediaCore?.Log(
                    MediaLogMessageType.Warning,
                    $"{nameof(MediaCommandManager)}.{nameof(OpenAsync)}: '{nameof(stream)}' cannot be null");

                return;
            }

            if (CanExecuteCommands == false)
            {
                return;
            }
            else
            {
                IsOpening.Value = true;
            }

            var command = new OpenCommand(this, stream);

            ExecutingCommand = command;
            ClearCommandQueue();

            try
            {
                if (command.HasCompleted)
                {
                    return;
                }

                await command.StartAsync();
            }
            catch (Exception ex)
            {
                MediaCore?.Log(
                    MediaLogMessageType.Error,
                    $"{nameof(MediaCommandManager)}.{nameof(OpenAsync)}: {ex.GetType()} - {ex.Message}");
            }
            finally
            {
                ExecutingCommand?.Complete();
                ExecutingCommand = null;
                IsOpening.Value  = false;
            }
        }
Example #7
0
        /// <summary>
        /// Processes the next command in the command queue.
        /// This method is called in every block rendering cycle.
        /// </summary>
        public void ProcessNext()
        {
            MediaCommand command = null;

            lock (SyncLock)
            {
                if (Commands.Count == 0)
                {
                    return;
                }
                command = Commands[0];
                Commands.RemoveAt(0);
            }

            command.Execute();
        }
Example #8
0
        /// <summary>
        /// Waits for the command to complete execution.
        /// </summary>
        /// <param name="command">The command.</param>
        private void WaitFor(MediaCommand command)
        {
            var waitTask = Task.Run(async() =>
            {
                while (command.HasCompleted == false && MediaElement.IsOpen)
                {
                    await Task.Delay(10);
                }
            });

            while (waitTask.IsCompleted == false)
            {
                // Pump invoke
                Dispatcher.CurrentDispatcher.Invoke(
                    DispatcherPriority.Background,
                    new Action(() => { }));
            }
        }
        /// <summary>
        /// Closes the specified media.
        /// This command gets processed in a threadpool thread.
        /// </summary>
        /// <returns>The awaitable close operation</returns>
        public DispatcherOperation Close()
        {
            if (CanExecuteCommands == false)
            {
                return(Dispatcher.CurrentDispatcher.CreatePumpOperation());
            }
            else
            {
                IsClosing.Value = true;
            }

            var command = new CloseCommand(this);

            ExecutingCommand = command;
            ClearCommandQueue();

            var backgroundTask = Task.Run(() =>
            {
                try
                {
                    if (command.HasCompleted)
                    {
                        return;
                    }
                    command.Execute();
                }
                catch (Exception ex)
                {
                    MediaElement?.Logger.Log(
                        MediaLogMessageType.Error,
                        $"{nameof(MediaCommandManager)}.{nameof(Close)}: {ex.GetType()} - {ex.Message}");
                }
                finally
                {
                    ExecutingCommand?.Complete();
                    ExecutingCommand = null;
                    IsClosing.Value  = false;
                }
            });

            var operation = Dispatcher.CurrentDispatcher.CreateAsynchronousPumpWaiter(backgroundTask);

            return(operation);
        }
        /// <summary>
        /// Closes the specified media.
        /// This command gets processed in a threadpool thread asynchronously.
        /// </summary>
        /// <returns>Returns the background task.</returns>
        public async Task CloseAsync()
        {
            if (CanExecuteCommands == false)
            {
                return;
            }
            else
            {
                IsClosing.Value = true;
            }

            var command = new CloseCommand(this);

            ExecutingCommand = command;
            ClearCommandQueue();

            var action = new Action(() =>
            {
                try
                {
                    if (command.HasCompleted)
                    {
                        return;
                    }
                    command.RunSynchronously();
                }
                catch (Exception ex)
                {
                    MediaCore?.Log(
                        MediaLogMessageType.Error,
                        $"{nameof(MediaCommandManager)}.{nameof(CloseAsync)}: {ex.GetType()} - {ex.Message}");
                }
                finally
                {
                    ExecutingCommand?.Complete();
                    ExecutingCommand = null;
                    IsClosing.Value  = false;
                }
            });

            await TaskEx.Run(action);
        }
        /// <summary>
        /// Processes the next command in the command queue.
        /// This method is called in every block rendering cycle.
        /// </summary>
        public void ProcessNext()
        {
            DumpQueue($"Before {nameof(ProcessNext)}", false);
            if (MediaCore.IsTaskCancellationPending)
            {
                return;
            }

            MediaCommand command = null;

            lock (SyncLock)
            {
                if (Commands.Count == 0)
                {
                    return;
                }
                command = Commands[0];
                Commands.RemoveAt(0);
            }

            try
            {
                ExecutingCommand = command;
                command.RunSynchronously();
                DumpQueue($"After {nameof(ProcessNext)}", false);
            }
            catch (Exception ex)
            {
                MediaCore?.Log(MediaLogMessageType.Error, $"{ex.GetType()}: {ex.Message}");
                throw;
            }
            finally
            {
                ExecutingCommand = null;
            }
        }