473,407 Members | 2,314 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

thread dead lock

Don
How to stop a process which is running in a separate thread!!!

I've got a class which performs some lengthy process in a background
(separate) thread. And this lengthy process raises events regularly to inform
the main thread of the progress (which is then displayed to the user).
Since the event is raised from another thread, i've used me.Invoke() to
update the ui properly.

However, my problem is in cancelling the process.
I need to be able to execute a method such as Cancel() which will return
only when the process has been cancelled.
Below is the code i've implemented.

How ever, the WaitOne() method will ALWAYS return FALSE.
I'm assuming this is becuase the WaitOne causes the current thread to wait
untill it receives a signal. & since the current thread is also in the
process of updating the UI, the background process thread is not able to send
the signal.
Hence a dead lock (if not for the timeout in the WaitOne())

I'm sure this HAS to be possible.
I need a mechanism to cancel the background process and WAIT till it
confirms that the process has been cancelled (i.e. wait till the process
notifies the main thread that the process has been cancelled).

How can this be done?

Below is a sample the code which outlies the above issue:
Public Class frmThreads
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Label1 As System.Windows.Forms.Label
<System.Diagnostics.DebuggerStepThrough()Private Sub
InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.Label1 = New System.Windows.Forms.Label
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(40, 120)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(128, 120)
Me.Button2.Name = "Button2"
Me.Button2.TabIndex = 1
Me.Button2.Text = "Button2"
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(32, 24)
Me.Label1.Name = "Label1"
Me.Label1.TabIndex = 2
Me.Label1.Text = "Label1"
'
'frmThreads
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "frmThreads"
Me.Text = "frmThreads"
Me.ResumeLayout(False)

End Sub

#End Region

Private _lengthyProcess As LengthyProcess
Private _counter As Integer
Private dlgIvokeProgress As New dlgProgress(AddressOf ShowProgress)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
_lengthyProcess = New LengthyProcess
AddHandler _lengthyProcess.Progress, AddressOf LengthyProcess_Progress

Dim start As New Threading.Thread(AddressOf StartProcess)
start.Start()
End Sub

Private Sub StartProcess()
_lengthyProcess.Start()
End Sub

Private Sub LengthyProcess_Progress(ByVal counter As Integer)
_counter = counter
Me.Invoke(dlgIvokeProgress)
End Sub

Private Delegate Sub dlgProgress()
Private Sub ShowProgress()
Me.Label1.Text = _counter
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
MsgBox(_lengthyProcess.Cancel)
End Sub
End Class

Public Class LengthyProcess

Public Event Progress(ByVal counter As Integer)

Private _counter As Integer
Private _cancelled As Boolean
Private _stopped As Threading.ManualResetEvent

Public Sub Start()
Do While _cancelled = False
_counter += 1

Threading.Thread.Sleep(100)
RaiseEvent Progress(_counter)
Loop

If _cancelled = True Then
_stopped.Set()
End If
End Sub

Public Function Cancel() As Boolean
_stopped = New Threading.ManualResetEvent(False)
_cancelled = True
'this will ALWAYS return FALSE
'how ever if i were to display a messagebox here and THEN
'execute the WaitOne(), it will return TRUE
'MsgBox("WaitOne will now return TRUE")

Return _stopped.WaitOne(5000, False)
End Function
End Class
Nov 20 '06 #1
2 1943
I think that you've tried to over-engineer it a tad and in the process have
confused yourself. Try this very simple code and then take it from there:

Note that the thread is now completely encapsulated within the
LengthyProcess class and the calling process does not need to know anything
about the thread. It only needs to know that the LengthyProcess class has a
Start method, a Cancel method and raises a Progress event.

In the LengthyProcess.Cancel method the call to _process.Join() has the
effect of waiting until the thread has actually finished which should be
somewhere up to 100 milliseconds plus the overhead for raising the Progress
event after the _cancel variable is set.

Also note that your UI thread (the form) will block each time the Progress
event is raised for as long at it takes to execute the ShowProgress method.
This means that ShowProgress must be as lean and mean as you can make it. As
an alternatively you could use BeginInvoke instead of Invoke which has the
effect of sending the ShowProgress method off to do it's stuff and
immediately allowing the LengthyProcess thread to continue.

<snip>all the preamble</snip

Private _lengthyProcess As LengthyProcess
Private _counter As Integer
Private Delegate Sub dlgProgress()
Private dlgIvokeProgress As New dlgProgress(AddressOf ShowProgress)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
_lengthyProcess = New LengthyProcess
AddHandler _lengthyProcess.Progress, AddressOf LengthyProcess_Progress
_lengthyProcess.Start()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
_lengthyProcess.Cancel
End Sub

Private Sub LengthyProcess_Progress(ByVal counter As Integer)
_counter = counter
Invoke(dlgIvokeProgress)
End Sub

Private Sub ShowProgress()
Label1.Text = _counter.ToString()
Label1.Update()
End Sub

End Class

Public Class LengthyProcess

Public Event Progress(ByVal counter As Integer)
Private _counter As Integer = 0
Private _process as Thread = Nothing
Private _cancel as Boolean = False

Public Sub Start()
_process = New Thread(AddressOf TheProcess)
_process.Start()
End Sub

Public Sub Cancel()
_cancel = True
_process.Join()
End Sub

Private Sub TheProcess()
While Not _cancel
_counter += 1
Thread.Sleep(100)
RaiseEvent Progress(_counter)
End While
End Sub

End Class
"Don" <Do*@discussions.microsoft.comwrote in message
news:B7**********************************@microsof t.com...
How to stop a process which is running in a separate thread!!!

I've got a class which performs some lengthy process in a background
(separate) thread. And this lengthy process raises events regularly to
inform
the main thread of the progress (which is then displayed to the user).
Since the event is raised from another thread, i've used me.Invoke() to
update the ui properly.

However, my problem is in cancelling the process.
I need to be able to execute a method such as Cancel() which will return
only when the process has been cancelled.
Below is the code i've implemented.

How ever, the WaitOne() method will ALWAYS return FALSE.
I'm assuming this is becuase the WaitOne causes the current thread to wait
untill it receives a signal. & since the current thread is also in the
process of updating the UI, the background process thread is not able to
send
the signal.
Hence a dead lock (if not for the timeout in the WaitOne())

I'm sure this HAS to be possible.
I need a mechanism to cancel the background process and WAIT till it
confirms that the process has been cancelled (i.e. wait till the process
notifies the main thread that the process has been cancelled).

How can this be done?

Below is a sample the code which outlies the above issue:
Public Class frmThreads
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Label1 As System.Windows.Forms.Label
<System.Diagnostics.DebuggerStepThrough()Private Sub
InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.Label1 = New System.Windows.Forms.Label
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(40, 120)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(128, 120)
Me.Button2.Name = "Button2"
Me.Button2.TabIndex = 1
Me.Button2.Text = "Button2"
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(32, 24)
Me.Label1.Name = "Label1"
Me.Label1.TabIndex = 2
Me.Label1.Text = "Label1"
'
'frmThreads
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "frmThreads"
Me.Text = "frmThreads"
Me.ResumeLayout(False)

End Sub

#End Region

Private _lengthyProcess As LengthyProcess
Private _counter As Integer
Private dlgIvokeProgress As New dlgProgress(AddressOf ShowProgress)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
_lengthyProcess = New LengthyProcess
AddHandler _lengthyProcess.Progress, AddressOf
LengthyProcess_Progress

Dim start As New Threading.Thread(AddressOf StartProcess)
start.Start()
End Sub

Private Sub StartProcess()
_lengthyProcess.Start()
End Sub

Private Sub LengthyProcess_Progress(ByVal counter As Integer)
_counter = counter
Me.Invoke(dlgIvokeProgress)
End Sub

Private Delegate Sub dlgProgress()
Private Sub ShowProgress()
Me.Label1.Text = _counter
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
MsgBox(_lengthyProcess.Cancel)
End Sub
End Class

Public Class LengthyProcess

Public Event Progress(ByVal counter As Integer)

Private _counter As Integer
Private _cancelled As Boolean
Private _stopped As Threading.ManualResetEvent

Public Sub Start()
Do While _cancelled = False
_counter += 1

Threading.Thread.Sleep(100)
RaiseEvent Progress(_counter)
Loop

If _cancelled = True Then
_stopped.Set()
End If
End Sub

Public Function Cancel() As Boolean
_stopped = New Threading.ManualResetEvent(False)
_cancelled = True
'this will ALWAYS return FALSE
'how ever if i were to display a messagebox here and THEN
'execute the WaitOne(), it will return TRUE
'MsgBox("WaitOne will now return TRUE")

Return _stopped.WaitOne(5000, False)
End Function
End Class

Nov 20 '06 #2
Don
Using BeginInvoke() did the trick
Thanks.
"Stephany Young" wrote:
I think that you've tried to over-engineer it a tad and in the process have
confused yourself. Try this very simple code and then take it from there:

Note that the thread is now completely encapsulated within the
LengthyProcess class and the calling process does not need to know anything
about the thread. It only needs to know that the LengthyProcess class has a
Start method, a Cancel method and raises a Progress event.

In the LengthyProcess.Cancel method the call to _process.Join() has the
effect of waiting until the thread has actually finished which should be
somewhere up to 100 milliseconds plus the overhead for raising the Progress
event after the _cancel variable is set.

Also note that your UI thread (the form) will block each time the Progress
event is raised for as long at it takes to execute the ShowProgress method.
This means that ShowProgress must be as lean and mean as you can make it. As
an alternatively you could use BeginInvoke instead of Invoke which has the
effect of sending the ShowProgress method off to do it's stuff and
immediately allowing the LengthyProcess thread to continue.

<snip>all the preamble</snip

Private _lengthyProcess As LengthyProcess
Private _counter As Integer
Private Delegate Sub dlgProgress()
Private dlgIvokeProgress As New dlgProgress(AddressOf ShowProgress)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
_lengthyProcess = New LengthyProcess
AddHandler _lengthyProcess.Progress, AddressOf LengthyProcess_Progress
_lengthyProcess.Start()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
_lengthyProcess.Cancel
End Sub

Private Sub LengthyProcess_Progress(ByVal counter As Integer)
_counter = counter
Invoke(dlgIvokeProgress)
End Sub

Private Sub ShowProgress()
Label1.Text = _counter.ToString()
Label1.Update()
End Sub

End Class

Public Class LengthyProcess

Public Event Progress(ByVal counter As Integer)
Private _counter As Integer = 0
Private _process as Thread = Nothing
Private _cancel as Boolean = False

Public Sub Start()
_process = New Thread(AddressOf TheProcess)
_process.Start()
End Sub

Public Sub Cancel()
_cancel = True
_process.Join()
End Sub

Private Sub TheProcess()
While Not _cancel
_counter += 1
Thread.Sleep(100)
RaiseEvent Progress(_counter)
End While
End Sub

End Class
"Don" <Do*@discussions.microsoft.comwrote in message
news:B7**********************************@microsof t.com...
How to stop a process which is running in a separate thread!!!

I've got a class which performs some lengthy process in a background
(separate) thread. And this lengthy process raises events regularly to
inform
the main thread of the progress (which is then displayed to the user).
Since the event is raised from another thread, i've used me.Invoke() to
update the ui properly.

However, my problem is in cancelling the process.
I need to be able to execute a method such as Cancel() which will return
only when the process has been cancelled.
Below is the code i've implemented.

How ever, the WaitOne() method will ALWAYS return FALSE.
I'm assuming this is becuase the WaitOne causes the current thread to wait
untill it receives a signal. & since the current thread is also in the
process of updating the UI, the background process thread is not able to
send
the signal.
Hence a dead lock (if not for the timeout in the WaitOne())

I'm sure this HAS to be possible.
I need a mechanism to cancel the background process and WAIT till it
confirms that the process has been cancelled (i.e. wait till the process
notifies the main thread that the process has been cancelled).

How can this be done?

Below is a sample the code which outlies the above issue:
Public Class frmThreads
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Label1 As System.Windows.Forms.Label
<System.Diagnostics.DebuggerStepThrough()Private Sub
InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.Label1 = New System.Windows.Forms.Label
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(40, 120)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(128, 120)
Me.Button2.Name = "Button2"
Me.Button2.TabIndex = 1
Me.Button2.Text = "Button2"
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(32, 24)
Me.Label1.Name = "Label1"
Me.Label1.TabIndex = 2
Me.Label1.Text = "Label1"
'
'frmThreads
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "frmThreads"
Me.Text = "frmThreads"
Me.ResumeLayout(False)

End Sub

#End Region

Private _lengthyProcess As LengthyProcess
Private _counter As Integer
Private dlgIvokeProgress As New dlgProgress(AddressOf ShowProgress)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
_lengthyProcess = New LengthyProcess
AddHandler _lengthyProcess.Progress, AddressOf
LengthyProcess_Progress

Dim start As New Threading.Thread(AddressOf StartProcess)
start.Start()
End Sub

Private Sub StartProcess()
_lengthyProcess.Start()
End Sub

Private Sub LengthyProcess_Progress(ByVal counter As Integer)
_counter = counter
Me.Invoke(dlgIvokeProgress)
End Sub

Private Delegate Sub dlgProgress()
Private Sub ShowProgress()
Me.Label1.Text = _counter
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
MsgBox(_lengthyProcess.Cancel)
End Sub
End Class

Public Class LengthyProcess

Public Event Progress(ByVal counter As Integer)

Private _counter As Integer
Private _cancelled As Boolean
Private _stopped As Threading.ManualResetEvent

Public Sub Start()
Do While _cancelled = False
_counter += 1

Threading.Thread.Sleep(100)
RaiseEvent Progress(_counter)
Loop

If _cancelled = True Then
_stopped.Set()
End If
End Sub

Public Function Cancel() As Boolean
_stopped = New Threading.ManualResetEvent(False)
_cancelled = True
'this will ALWAYS return FALSE
'how ever if i were to display a messagebox here and THEN
'execute the WaitOne(), it will return TRUE
'MsgBox("WaitOne will now return TRUE")

Return _stopped.WaitOne(5000, False)
End Function
End Class


Nov 20 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Torsten Mohr | last post by:
Hi, i write an extension module in C at the moment. This module does some work on some own data types that consist of some values. The functions that can change the data are written in C. ...
4
by: fred | last post by:
I use a Synclock in a secondary thread and also stop the thread using the abort method. If the abort occurs while the thread is in the Synclock will the SyncLock always be released before the...
6
by: Shanmugasundaram Doraisamy | last post by:
Dear Group, Is there a way to increase the time of Dead Lock? The default is set to 1000 msec. Regards, Shan. ---------------------------(end of broadcast)--------------------------- TIP 7:...
17
by: euan_woo | last post by:
Hi, Sometimes my program stops and when I break it I see 2 threads both waiting at a lock statement trying to lock the same object. If I look up the call stack of these threads there aren't any...
2
by: titan nyquist | last post by:
I thought I need something like this, but it turns out I don't. I'm still interested if this can be done: Can you do a multi-thread "lock", that locks out everything else, all other threads,...
4
by: LamSoft | last post by:
It seems that my program is dead lock after running this sentence (bold) private delegate void updateBuildingDetailCallBack(String key, String Value); private void updateBuildingDetail(String...
0
by: vaskarbasak | last post by:
Hi All, we have a large table having 60 lakhs and more data.so we are facing a problem when we are executing insert or update query. as a result our DB is very slow and sometimes we are facing...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.