Member 14068274 Ответов: 3

Мой индикатор выполнения не закрывается, когда процесс завершается 100%


Привет,

Я добавил индикатор выполнения в свой код c#, чтобы отслеживать выполнение работы.

Индикатор выполнения открывается и отлично работает, но он не закрывается, когда процесс завершен. и это бросает меня "
System.InvalidOperationException: 'A task may only be disposed if it is in a completion state (RanToCompletion, Faulted or Canceled).'
"

Что я уже пробовал:

{
            var t = Task.Run(() => Showprogress());
            //Graphics g = e.Graphics;
            int i = 0;
            int j = 1;
            DirectoryInfo dinfo = new DirectoryInfo(filePath);
            FileInfo[] Files = dinfo.GetFiles("*.jpg");
            List<mat> imageStructure = new List<mat>();
            Dictionary<string, int> noOfObjects = new Dictionary<string, int>();
            foreach (FileInfo file in Files)
            {
                Image<Bgr, Byte> image = new Image<Bgr, Byte>(file.FullName);
                if (image != null)
                {
                    if (i < myprogress.getMaxValue())
                        myprogress.updateprogress(i);
                    else
                    {
                        j++;
                        myprogress.setMaxValue(j*100);
                    }
                    i++;
                    myRectangles.Clear();
                    var detections = this._yoloWrapper.Detect(ImageToByte(image.Bitmap)).ToList();
                    foreach (var dect in detections)
                    {
                        if (CheckMarkingForDisplay(dect))
                            if (noOfObjects.Keys.Contains(dect.Type))
                                noOfObjects[dect.Type] += 1;


                            else
                                noOfObjects.Add(dect.Type, 1);
                        

                    }
                }
            }
            String csv = String.Join(Environment.NewLine, "Object Type, Count" + Environment.NewLine);
            csv = csv + String.Join(Environment.NewLine, noOfObjects.Select(d => d.Key + "," + d.Value));
            if (!Directory.Exists(@"C:\CountingObject\" + dinfo.Name))
                Directory.CreateDirectory(@"C:\CountingObject\" + dinfo.Name);
            System.IO.File.WriteAllText(@"C:\CountingObject\" + dinfo.Name + @"\ObjectCount.csv", csv);
           myprogress.updateprogress(j*100);
           t.Dispose();      //the error is occurring here
           myprogress.Close();
        }



Функции, которые я использую для индикатора выполнения, таковы
using System.Windows.Forms;

namespace SIMSVisionTool
{
    public partial class progressBar : Form
    {
        public progressBar(int maxvalue)
        {
            InitializeComponent();
            this.progressBar1.Value = 0;
            this.progressBar1.Maximum = maxvalue;
        }

        public void updateprogress(int i)
        {
            this.progressBar1.Invoke((MethodInvoker)delegate
            {
                // Running on the UI thread
                this.progressBar1.Value = i;
            });
        }

        public int getMaxValue()
        {
            return this.progressBar1.Maximum;
        }

        public void setMaxValue(int maxvalue)
        {
            this.progressBar1.Invoke((MethodInvoker)delegate
            {
                // Running on the UI thread
                this.progressBar1.Maximum = maxvalue;
            });
        }
    }
}

Richard MacCutchan

Сделайте то, что я предложил вчера, и используйте правильный класс ProgressBar, который предоставляется в файле .NET.

3 Ответов

Рейтинг:
1

OriginalGriff

Первое, что нужно сделать, это посмотреть, какой именно тип myprogress это - это не стандартная панель прогресса Windows, потому что у нее нет updateprogress метод.

Так что найдите код для индикатора прогресса yoru и начните смотреть на экран. ShowProgress метод в вашем основном коде, плюс updateprogress и Close методы в вашем классе управления прогрессом.

Извините, но мы ничего не можем сделать для вас!


Member 14068274

не могли бы вы сказать мне, пожалуйста, где можно получить код для yoru progress bar

OriginalGriff

Ваш Набор Инструментов Visual Studio...

Рейтинг:
0

Richard MacCutchan

Почему вы делаете жизнь трудной для себя (и других)? Использовать стандартный Класс ProgressBar (System.Окна.Формы) | Microsoft Docs[^].


Рейтинг:
0

clement wanjau

Вы запустили метод ShowProgress() в отдельном потоке и не можете просто избавиться от потока, так как он может находиться в середине важной задачи или удерживать дескриптор некоторых ресурсов. Поэтому лучше всего добавить synchronizationcontext или создать метод, который запускает другую реальную задачу и передает ее как действие. Информация, которую вы предоставили, ограничена, поэтому я не запускал тест, чтобы убедиться, что он работает, но вы должны попробовать это, и я надеюсь, что вы получите общее представление о том, как подойти к проблеме
Это форма, которая показывает прогресс



using System.Windows.Forms;

namespace SIMSVisionTool
{
    public partial class progressBar : Form
    {

        private Action _Action{ get; set; }

        public progressBar(int maxvalue, Action _action)
        {
            InitializeComponent();
             if(_action == null)
                Throw new NullArgumentException("The worker thread is null");
            this._Action = _action;
            this.progressBar1.Value = 0;
            this.progressBar1.Maximum = maxvalue;
        }

       public override void OnLoad(){
           // Load the page on a separate thread
                Task.Factory.StartNew(_Action).ContinueWith(t=>{t.Close();}, TaskScheduler.FromCurrentSynchronizationContext());
       }

        public void updateprogress(int i)
        {
            this.progressBar1.Invoke((MethodInvoker)delegate
            {
                // Running on the UI thread
                this.progressBar1.Value = i;
            });
        }

        public int getMaxValue()
        {
            return this.progressBar1.Maximum;
        }

        public void setMaxValue(int maxvalue)
        {
            this.progressBar1.Invoke((MethodInvoker)delegate
            {
                // Running on the UI thread
                this.progressBar1.Maximum = maxvalue;
            });
        }
    }
}


Вот способ реализовать его на задаче
class myWorkerClass{
        
        public void StartWork(){
            // Here you initialize the form passing in the maximum value and the method to execute asyncronously
            myprogress = new progressBar(maxValue, getImages);

        }
          
// The helper Method To Pass In as the action delegate 


    private void getImages(){
        int i = 0;
        int j = 1;
        DirectoryInfo dinfo = new DirectoryInfo(filePath);
        FileInfo[] Files = dinfo.GetFiles("*.jpg");
        List<mat> imageStructure = new List<mat>();
        Dictionary<string, int> noOfObjects = new Dictionary<string, int>();
        foreach (FileInfo file in Files)
        {
            Image<Bgr, Byte> image = new Image<Bgr, Byte>(file.FullName);
            if (image != null)
            {
                if (i < myprogress.getMaxValue())
                    myprogress.updateprogress(i);
                else
                {
                    j++;
                    myprogress.setMaxValue(j*100);
                }
                i++;
                myRectangles.Clear();
                var detections = this._yoloWrapper.Detect(ImageToByte(image.Bitmap)).ToList();
                foreach (var dect in detections)
                {
                    if (CheckMarkingForDisplay(dect))
                        if (noOfObjects.Keys.Contains(dect.Type))
                            noOfObjects[dect.Type] += 1;


                        else
                            noOfObjects.Add(dect.Type, 1);
                    

                }
            }
        }
        String csv = String.Join(Environment.NewLine, "Object Type, Count" + Environment.NewLine);
        csv = csv + String.Join(Environment.NewLine, noOfObjects.Select(d => d.Key + "," + d.Value));
        if (!Directory.Exists(@"C:\CountingObject\" + dinfo.Name))
            Directory.CreateDirectory(@"C:\CountingObject\" + dinfo.Name);
        System.IO.File.WriteAllText(@"C:\CountingObject\" + dinfo.Name + @"\ObjectCount.csv", csv);
       myprogress.updateprogress(j*100);
   }
}