ObservableQueue пусто при попытке удаления из очереди - PullRequest
0 голосов
/ 30 сентября 2019

Я реализовал свою собственную ObservableQueue следующим образом:

public class ObservableQueue<T> : Queue<T>, INotifyPropertyChanged, INotifyCollectionChanged
    {
        public event NotifyCollectionChangedEventHandler CollectionChanged;
        public event PropertyChangedEventHandler PropertyChanged;

        public ObservableQueue() : base() { }
        public ObservableQueue(IEnumerable<T> collection) : base(collection) { }
        public ObservableQueue(int capacity) : base(capacity) { }

        public virtual new T Enqueue(T item)
        {
            lock (this)
            {
                base.Enqueue(item);
            }
            OnCollectionChanged(NotifyCollectionChangedAction.Add, item);

            return item;
        }

        public virtual new T Dequeue()
        {
            lock (this)
            {
                var item = base.Dequeue();
                return item;
            }
        }

        protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action, T item)
        {
            CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(
                action
                , item
                , item == null ? -1 : 0)
            );

            OnPropertyChanged(nameof(Count));
        }

        protected virtual void OnPropertyChanged(string proertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(proertyName));
        }
    }

Я подписываюсь на очередь в MainWindow:

paths.CollectionChanged += Process;

Когда файл добавляется в определенную папку,Я ставлю в очередь:

private void FileCreated(Object sender, FileSystemEventArgs e)
      {
          try
           {
                paths.Enqueue(currentPath);
           } catch (InvalidOperationException exception)
           {
               string messageBoxText = exception.Message;
               MessageBoxButton button = MessageBoxButton.OK;
               System.Windows.MessageBox.Show(messageBoxText, "Error", button);
          } 
       }

Это вызывает CollectionChanged в очереди, и я запускаю это следующим образом:

private async void Process(object sender, NotifyCollectionChangedEventArgs e)
        {

            var currentPath = paths.Dequeue();
            await UploadFile(currentPath);
            Thread.Sleep(5000);
            try
            {
                 MoveFile(currentPath, outputFolderPath, System.IO.Path.GetFileName(currentPath));
             } catch (IOException IOE)
            {
                 Console.WriteLine(IOE.StackTrace);
            }
       }

Но я получаю следующую ошибку при попытке снять очередь:

System.InvalidOperationException: 'Очередь пуста.'

Я не могу понять, как возможно, чтобы очередь была пустой?

Iтакже время от времени получайте следующее исключение:

Информация об исключении: System.InvalidOperationException в System.ThrowHelper.ThrowInvalidOperationException (System.ExceptionResource) в System.Collections.Generic.Queue 1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Dequeue() at Program.Utilities.ObservableQueue 1 [[System .__ Canon, mscorlib, версия = 4.0.0.0, культура = нейтральная, PublicKeyToken = b77a5c561934e089]]. Dequeue () в Program.MainWindow + d__11.MoveNext () в System.Runtime.CompilerServices.AsyncMethodBuilderCore <6> c>.Object) в System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object) в System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, BooleanteR. (System. _ThreadPoolWaitCallback.PerformWaitCallback ()

1 Ответ

0 голосов
/ 30 сентября 2019

Ваш пример кода неполон, так как мы не видим что еще вы делаете с очередью, так что я просто догадываюсь здесь. Может ли быть так, что использование «async void» в качестве подключенного обработчика событий заставляет Process () работать асинхронно, пока вы продолжаете мутировать свою очередь, тем самым заставляя этот код чередоваться, поскольку пул потоков считает нужным в высокой степени недетерминированным образом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...