Multithreaded queue in C #

I was tasked with working on a boot queue system, but I'm a little confused about where to start.

Essentially, we need to have something like a boot manager (but not so full). We have about 20-100 files to download, we provide the user with a user interface (with a list) that allows them to pause, stop or move the priorities of tasks.

What confuses me is the data structure that needs to be used, the order of priorities is a way out of my research, but I'm confused about how to make it work. Do I have a background thread that looks in the queue and raises the next task and moves it forward? I also need to ensure progress, since the files are downloaded - they are quite large, sometimes 120 MB (but local, so no more than 10 minutes).

Sometimes they have to pause the task and complete the task higher in the queue, since it is considered urgent.

This is not a boot manager, so no problems with throttling, etc. How do people write such things?

I was thinking of having an interface, such as IDownloadTask, which describes the task to be executed, has several properties and an event to expose its Progress (which is connected when tasks are completed).

Then put this IDownloadTask in the priority queue. The background worker picks it (PriorityQUeue priority should be synchronized, I think), and then executes the .Execute () method in the implementation of the interface in a separate thread.

Does that sound reasonable? Are there any specific examples anyone can show me?

EDIT

Thanks for the answer and vote of confidence, I should mention that I am using .NET 2.0 (we cannot move higher due to Windows compatibility requirements for Windows 9x).

+3
3

, , . , . , , .

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ThreadWithDataReturnExample
{
    public partial class Form1 : Form
    {
        private Thread thread1 = null;

        public Form1()
        {
            InitializeComponent();

            thread1 = new Thread(new ThreadStart(this.threadEntryPoint));
            Thread1Completed += new AsyncCompletedEventHandler(thread1_Thread1Completed);
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            thread1.Start();
            //Alternatively, you could pass some object
            //in such as Start(someObject);
            //With apprioriate locking, or protocol where
            //no other threads access the object until
            //an event signals when the thread is complete,
            //any other class with a reference to the object 
            //would be able to access that data.
            //But instead, I'm going to use AsyncCompletedEventArgs 
            //in an event that signals completion
        }

        void thread1_Thread1Completed(object sender, AsyncCompletedEventArgs e)
        {
            if (this.InvokeRequired)
            {//marshal the call if we are not on the GUI thread                
                BeginInvoke(new AsyncCompletedEventHandler(thread1_Thread1Completed),
                  new object[] { sender, e });
            }
            else
            {
                //display error if error occurred
                //if no error occurred, process data
                if (e.Error == null)
                {//then success

                    MessageBox.Show("Worker thread completed successfully");
                    DataYouWantToReturn someData = e.UserState as DataYouWantToReturn;
                    MessageBox.Show("Your data my lord: " + someData.someProperty);

                }
                else//error
                {
                    MessageBox.Show("The following error occurred:" + Environment.NewLine + e.Error.ToString());
                }
            }
        }

        #region I would actually move all of this into it own class
            private void threadEntryPoint()
            {
                //do a bunch of stuff

                //when you are done:
                //initialize object with data that you want to return
                DataYouWantToReturn dataYouWantToReturn = new DataYouWantToReturn();
                dataYouWantToReturn.someProperty = "more data";

                //signal completion by firing an event
                OnThread1Completed(new AsyncCompletedEventArgs(null, false, dataYouWantToReturn));
            }

            /// <summary>
            /// Occurs when processing has finished or an error occurred.
            /// </summary>
            public event AsyncCompletedEventHandler Thread1Completed;
            protected virtual void OnThread1Completed(AsyncCompletedEventArgs e)
            {
                //copy locally
                AsyncCompletedEventHandler handler = Thread1Completed;
                if (handler != null)
                {
                    handler(this, e);
                }
            }
        #endregion

    }
}
+2

#, , , , .

+1

-, :

# AutoResetEvent

, , , , , ..

0

Source: https://habr.com/ru/post/1715954/


All Articles