Thread class in Framework 2.0

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

In the .NET Framwrok 2.0 the methods

Suspend();
Resume();

of the Thread Class are marked as Obsolete

[ObsoleteAttribute("Thread.Resume has been deprecated. Please use other
classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to
synchronize Threads or protect resources.
http://go.microsoft.com/fwlink/?linkid=14202", false)]
public void Resume();

How if I have a backgroud thread ( say a very long and time consuming
simulation ) and I want to easily give the use the ability to suspend it to
use his pc for a while without that load ?
And then resume it ?
I do beleve that this is not the the right way to sincornize Threads but
what if you want just to suspend a thread.
 
I have not researched the solution, so I can only offer guidance in general.
This should give some background for the reasoning:
http://blogs.msdn.com/oldnewthing/archive/2003/12/09/55988.aspx

Microsoft's suggestion is to use another class, like a Monitor, Mutex, etc.
to fulfill your need. The reasoning is simple. Suspend can leave an object in
a state where it is blocked, causing deadlocks for other processes attempting
to gain access.

Take the Monitor, for example. It is better to have the monitor kick the
thread off the object and free it up for other work than it is to have the
work simply suspended. The downside, of course, is you must reconnect the
thread to the object to begin work again.

If you are sure that nothing else can use the object other than the thread
in question, you can continue to use the deprecated methods, but realize that
you are inviting potential issues in the future.

If it is your own object that might be blocked, you can make it "thread
safe" by making a struct out of it, forcing it on the heap. Note, however,
that this means you will end up with the "object" in many memory spaces. You
can then suspend without worrying about deadlocks. This does not solve the
deprecated issue, but it certainly makes working with deprecated methods
safer. NOTE, however, that you can go overboard with structs, causing a stack
overflow (if you make all "objects" into structure, for example).

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

***************************
Think Outside the Box!
***************************
 
Dodo,
In addition to the other comments.

Here is a an example I posted February 2005 of a Worker class using a
ManualResetEvent to control suspending & resuming.

Public Class Worker

Public Delegate Sub Work()

Private ReadOnly m_work As Work
Private ReadOnly m_arg As Object
Private ReadOnly m_event As ManualResetEvent
Private ReadOnly m_thread As Thread

<ThreadStatic()> _
Private Shared m_current As Worker

Public Sub New(ByVal work As Work, ByVal arg As Object, ByVal name
As String)
m_work = work
m_arg = arg
m_event = New ManualResetEvent(True)
m_thread = New Thread(AddressOf Start)
m_thread.Name = name
m_thread.IsBackground = True
m_thread.Start()
End Sub

Private Sub Start()
m_current = Me
m_work.Invoke()
End Sub

Public Shared ReadOnly Property CurrentWorker() As Worker
Get
Return m_current
End Get
End Property

Public ReadOnly Property Arg() As Object
Get
Return m_arg
End Get
End Property

Public ReadOnly Property Name() As String
Get
Return m_thread.Name
End Get
End Property

Public Sub Suspend()
If Thread.CurrentThread Is m_thread Then
Throw New InvalidOperationException("Suspend should not be
called from the worker thread!")
End If
m_event.Reset()
End Sub

Public Sub [Resume]()
If Thread.CurrentThread Is m_thread Then
Throw New InvalidOperationException("Resume should not be
called from the worker thread!")
End If
m_event.Set()
End Sub

Public Sub WaitForTermination()
If Thread.CurrentThread Is m_thread Then
Throw New InvalidOperationException("WaitForTermination
should not be called from the worker thread!")
End If
m_thread.Join()
End Sub

Public Sub CheckSuspend()
If Not Thread.CurrentThread Is m_thread Then
Throw New InvalidOperationException("CheckSuspend should
only be called from the worker thread!")
End If
m_event.WaitOne()
End Sub

End Class



To see how it works try something like:

Private Sub Work()
For index As Integer = 1 To 50
Worker.CurrentWorker.CheckSuspend()
Debug.WriteLine(index, Worker.CurrentWorker.Name)
Dim value As Double = DirectCast(Worker.CurrentWorker.Arg,
Double)
Thread.Sleep(TimeSpan.FromSeconds(value))
Next
End Sub

Public Sub Main()
Dim worker1 As New Worker(AddressOf Work, 0.25, "worker1")
Dim worker2 As New Worker(AddressOf Work, 0.5, "worker2")
Dim worker3 As New Worker(AddressOf Work, 0.75, "worker3")

Debug.WriteLine("Pausing 5 seconds", "Main")
Thread.Sleep(TimeSpan.FromSeconds(5))
worker1.Suspend()

Debug.WriteLine("Pausing 5 seconds", "Main")
Thread.Sleep(TimeSpan.FromSeconds(5))
worker2.Suspend()

Debug.WriteLine("Pausing 5 seconds", "Main")
Thread.Sleep(TimeSpan.FromSeconds(5))
worker3.Suspend()

Debug.WriteLine("Pausing 1 seconds", "Main")
Thread.Sleep(TimeSpan.FromSeconds(1))

worker1.Resume()
worker2.Resume()
worker3.Resume()

Debug.WriteLine("Waiting for Termination", "Main")
worker1.WaitForTermination()
worker2.WaitForTermination()
worker3.WaitForTermination()

End Sub

The above sample was initially posted in a thread titled "Technique for
Pausing Worker Thread" in the microsoft.public.dotnet.languages.vb newsgroup
between 21 Jan 2005 & 23 Jan 2005.

Hope this helps
Jay


|
| In the .NET Framwrok 2.0 the methods
|
| Suspend();
| Resume();
|
| of the Thread Class are marked as Obsolete
|
| [ObsoleteAttribute("Thread.Resume has been deprecated. Please use other
| classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore,
to
| synchronize Threads or protect resources.
| http://go.microsoft.com/fwlink/?linkid=14202", false)]
| public void Resume();
|
| How if I have a backgroud thread ( say a very long and time consuming
| simulation ) and I want to easily give the use the ability to suspend it
to
| use his pc for a while without that load ?
| And then resume it ?
| I do beleve that this is not the the right way to sincornize Threads but
| what if you want just to suspend a thread.
|
|
 
Dodo Cibelli said:
In the .NET Framwrok 2.0 the methods

Suspend();
Resume();

of the Thread Class are marked as Obsolete

Thank goodness for that.
[ObsoleteAttribute("Thread.Resume has been deprecated. Please use other
classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to
synchronize Threads or protect resources.
http://go.microsoft.com/fwlink/?linkid=14202", false)]
public void Resume();

How if I have a backgroud thread ( say a very long and time consuming
simulation ) and I want to easily give the use the ability to suspend it to
use his pc for a while without that load ?
And then resume it ?
I do beleve that this is not the the right way to sincornize Threads but
what if you want just to suspend a thread.

You use Monitor.Wait/Notify, or Auto/ManualResetEvents, with the co-
operation of the thread in question.

See http://www.pobox.com/~skeet/csharp/threads
 
Back
Top