Home > Software design >  Start Stop thread from class
Start Stop thread from class

Time:06-27

I want to start / stop a thread in order not to block the UI using button

public partial class Program_Form : Form
{
    readonly BackgroundWorker m_oWorker;

    [STAThread]
    private void Program_Form_Load(object sender, EventArgs e)
    {
        // long code here 
    }

    private async void DGW6BtnPrint_Click(object sender, EventArgs e)
    {
        Work.Printer_ Print = new Work.Printer_();

        await Task.Run(() =>
        {
            Print.Print_File(this, dataGridView6, StatusText, progressBar1,
                varriablesStatus);
        });
    }

    public void BTN6PPauza_Click(object sender, EventArgs e)
    {
        //What i had tried 
        //_canceller.Dispose();
        //_canceller.Cancel();
        // varriablesStatus = false;
        //thread2.break;
        //autoResetEvent.WaitOne();
        //thread2.Join();
        //_manualResetEvent.Reset();
        //thread2.Abort();
        //_pauseEvent.Reset();
        //varriablesStatus = "Pause";
        //Print_Actions();
    }
}

Referenced class:

namespace OfficeTools.Work
{
    class Printer_
    {
        public void Print_File(Program_Form callForm, DataGridView DGW,
            TextBox Status, ProgressBar Progress, bool varriablesStatus)
        {
            foreach (DataGridViewRow Row in DGW.Rows)
            {
                file = DGW.Rows[Row.Index].Cells[4].Value.ToString();
                PrintFiles.Print_Word(file);
            }
        }
    }
}

How can I start stop pause resume the thread because nothing worked from what I had tried, I think the problem is from the foreach loop I never used threads, and I can not find an example similar with mine in order to understand how should I do.

CodePudding user response:

i made this work, i do not know if it is the right way but for the moment it works

public partial class Program_Form : Form
{
    readonly BackgroundWorker m_oWorker;
    CancellationTokenSource _tokenSource = null;

    [STAThread]
    private void Program_Form_Load(object sender, EventArgs e)
    {
        // long code here 
    }

    private async void DGW6BtnPrint_Click(object sender, EventArgs e)
    {
            _tokenSource = new CancellationTokenSource();
            var token = _tokenSource.Token;


            Work.Printer_ Print = new Work.Printer_();
            await Task.Run(() =>
            {
                    Print.Print_File(this, dataGridView6, StatusText, progressBar1, token);
            });
    }

    public void BTN6PPauza_Click(object sender, EventArgs e)
    {
     _tokenSource.Cancel();
    }
}

Referenced class:

namespace OfficeTools.Work
{
    class Printer_
    {
         public void Print_File(Program_Form callForm, DataGridView DGW, TextBox Status, ProgressBar Progress, CancellationToken Token)
        {
            foreach (DataGridViewRow Row in DGW.Rows)
            {
                file = DGW.Rows[Row.Index].Cells[4].Value.ToString();
                PrintFiles.Print_Word(file);

               if (Token.IsCancellationRequested)
               {
                  try
                  {
                    Winword.Quit(ref missing, ref missing, ref missing);
                    winword = null;
                   }
                  catch { }
                  return;
               }
            }
        }
    }
}

Kind regards all

CodePudding user response:

What you are asking implies that you want to use the Thread.Suspend and Thread.Resume methods. Possibly like this:

private volatile Thread _printThread;

private async void DGW6BtnPrint_Click(object sender, EventArgs e)
{
    Work.Printer_ Print = new Work.Printer_();

    await Task.Run(() =>
    {
        _printThread = Thread.CurrentThread;
        try
        {
            Print.Print_File(this, dataGridView6, StatusText, progressBar1,
                varriablesStatus);
        }
        finally { _printThread = null; }
    });
}

public void BTN6PPauza_Click(object sender, EventArgs e)
{
    var printThread = _printThread;
    if (printThread != null)
    {
        if (printThread.ThreadState.HasFlag(ThreadState.Running))
        {
            printThread.Suspend();
        }
        else if (printThread.ThreadState.HasFlag(ThreadState.Suspended))
        {
            printThread.Resume();
        }
    }
}

The documentation of these two methods includes several cautionary warnings that discourage usage:

Thread.Suspend has been deprecated. Use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.

Do not use the Suspend and Resume methods to synchronize the activities of threads. You have no way of knowing what code a thread is executing when you suspend it. If you suspend a thread while it holds locks during a security permission evaluation, other threads in the AppDomain might be blocked. If you suspend a thread while it is executing a class constructor, other threads in the AppDomain that attempt to use that class are blocked. Deadlocks can occur very easily.

It's up to you if you want to accept these risks. If you ask me, you shouldn't.


Note: The Suspend and Resume methods are not supported on .NET Core and later platforms. On these platforms they throw a PlatformNotSupportedException exception. You can use them only if you target the .NET Framework platform.

  • Related