-1

I have this process with two threads in it. and a form that has buttons (start, suspend, pause, resume). whenever I suspend using the EWH.WaitOne() the whole application freezes (suspends) and I can't press the resume button any more

Is there a way to suspend the 2 threads only while the form keeps on running? (thread 1 and 2 in my code)

 public partial class Form1 : Form
    {
        public static System.Timers.Timer timer;
        static Thread Thread1;
        static Thread Thread2;
        private static EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);


        static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            using (var writer = File.AppendText("WriteTo.txt"))
            {
                writer.AutoFlush = true;
                writer.WriteLine(e.SignalTime);
            }


        }
        static void method1()
        {
            string text = "";
            using (FileStream fs = File.Open("C:\\Users\\Wissam\\Documents\\Visual Studio 2010\\Projects\\Proc1\\Proc1\\bin\\Debug\\MyFile.txt", FileMode.Open, FileAccess.Read, FileShare.None))
            {
                int length = (int)fs.Length;
                byte[] b = new byte[length];
                UTF8Encoding temp = new UTF8Encoding(true);

                while (fs.Read(b, 0, b.Length) > 0)
                {
                    text += temp.GetString(b);
                }
                using (FileStream fs1 = File.Open("C:\\Users\\Wissam\\Documents\\Visual Studio 2010\\Projects\\Proc1\\Proc1\\bin\\Debug\\MyFile1.txt", FileMode.Open, FileAccess.Write, FileShare.None))
                {
                    fs1.Write(temp.GetBytes(text), 0, temp.GetByteCount(text));
                    Thread.Sleep(1000);
                }

            }
        }
        static void method2()
        {
            timer = new System.Timers.Timer(1000);
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.Interval = 1000;
            timer.Enabled = true;


        }
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Wissam Habib
  • 9
  • 1
  • 7
  • 1
    What's even creating the other threads? It's really not clear what you're trying to achieve here. I suspect that `WaitOne()` doesn't do what you think it does. – Jon Skeet Jan 13 '13 at 09:12
  • I just need to use several threads, don't worry about ther functionalities – Wissam Habib Jan 13 '13 at 09:12
  • yes i suspect that to. but i need something similar to the thread.suspend() that would stop the writing to files – Wissam Habib Jan 13 '13 at 09:13
  • Did you use `WaitOne()` in UI thread? – Alexander Balte Jan 13 '13 at 09:20
  • I strongly suspect that @JonSkeet is correct and that you are calling the event WaitOne() from the GUI thread - that will stuff up your form response for sure. Put the event wait in the 'while (fs.Read(b, 0, b.Length)' loop in your thread method. Also, why the 'Sleep(1000)' call? – Martin James Jan 13 '13 at 09:20
  • the thing is, this is a part of several C# files, I need the Thread.Sleep to get some delay for the other parts, it's not my problem. my only problem is that whenever I press suspend, i need to stop both threads only. (Thread 1 being method 1 and 2 is 2) – Wissam Habib Jan 13 '13 at 09:22
  • @WissamHabib: Your `method2` method hardly does anything though - it just starts a timer. It sounds like you'd *actually* want to suspend the timer. – Jon Skeet Jan 13 '13 at 09:26
  • method2 only writes the time every second, so if suspending the timer works, i'd try that as well. – Wissam Habib Jan 13 '13 at 09:28

1 Answers1

2

Suspending threads directly is basically a risky proposition - from another thread, you can't tell when the "target" thread is in the middle of something critical. For example, you don't want to suspend a thread while it owns a lock that you'll want to acquire from another thread.

You can certainly use a wait handle - I'd suggest ManualResetEvent in this case. The controlling thread would call Set to give the green light to other threads, and Reset to "ask" them to suspend. The other threads would then call WaitOne periodically (usually as the first part of a loop), blocking when the event isn't set.

You may well want to put a time-out on the wait call, so that you can periodically check the state of other things (e.g. whether to quit completely) - it depends on your situation. Use the return value of WaitOne to find out whether the event was actually signalled, or whether you just timed out.

Another alternative would be to use Monitor.Pulse / Monitor.PulseAll / Monitor.Wait to indicate state changes, and keep a separate flag saying whether or not the thread should do work. You'd need to be careful around the memory model to check that your threads see changes written by each other though.

Given that you appear to be doing work once per second, yet another alternative - possibly simpler would be to do all the work in a timer which you simply enable and disable appropriately.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194