|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
SyncLock Required?am using system.timer is there already this type of lock behaviour in place? I need to assure that I'm only selecting one distinct record at a time per thread... Public Class Form1 Private MessageArray() As MessageHandler Private MH As MessageHandler Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load MH = New MessageHandler Dim i As Integer Dim iTo As Integer = 4 '4 threads Dim iFrom As Integer = 1 ReDim MessageArray(iTo - iFrom) Dim Msg As MessageHandler For i = iFrom To iTo Msg = New MessageHandler() MessageArray(i - iFrom) = Msg 'pass parameters to the new thread Msg.i = i Msg.MainForm = Me Dim ts As ThreadStart ts = New ThreadStart(AddressOf Msg.ProcessingOutboundThread) Dim wrkThread As Thread wrkThread = New Thread(ts) Msg.CurrentThread = wrkThread wrkThread.SetApartmentState(ApartmentState.STA) wrkThread.Name = i.ToString() 'for easier tracing wrkThread.Start() Next 'end start End Sub End Class Class MessageHandler Public MainForm As Form1 Public i As Integer Public CurrentThread As Thread Public iThreadId As Integer Public cnString As String = "server=servername;database=dbname;uid=username;pwd=password" Private WithEvents Timer1 As System.Timers.Timer Private Sub Timer1_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed iThreadId = Thread.CurrentThread.GetHashCode() Dim cn As SqlConnection cn = New SqlConnection(cnString) Dim cmd As SqlCommand Dim dtr As SqlDataReader Try Try cmd = New SqlCommand("select top 1 * from queue_table where time_to_send=1", cn) cn.Open() dtr = cmd.ExecuteReader() If dtr.HasRows() = True Then dtr.Read() Dim varE As String = dtr("employeetosendto") Dim varM As String = dtr("employeemessageaddress") dtr.Close() cmd = New SqlCommand("update queue_table set time_to_send=0 where employee='" & varE & "'", cn) cmd.ExecuteNonQuery() Call_Send_Message_Sub_Here 'call another sub pass employeemessageadress as param cmd = New SqlCommand("update queue_table set sentmessage=1 where employee='" & varE & "'", cn) cmd.ExecuteNonQuery() end if Catch ex As Exception msgbox(ex.Message.ToString()) Finally If cn.State = ConnectionState.Open Then cn.Close() End Try End If Catch ex As Exception msgbox(ex.Message.ToString()) Finally If cn.State = ConnectionState.Open Then cn.Close() End Try End Sub Public Sub ProcessingOutboundThread() Dim iThreadId As Integer iThreadId = Thread.CurrentThread.GetHashCode() Timer1 = New System.Timers.Timer Timer1.Interval = 5000 ' 5 seconds Timer1.Start() Application.Run() End Sub End Class I'd appreciate any feedback on how I can make this a more threadsafe app or more stable app. Thanks a lot. Jay Jay wrote:
Show quoteHide quote > Given the following code I am wondering if SyncLock is required. Because I Jay,> am using system.timer is there already this type of lock behaviour in place? > I need to assure that I'm only selecting one distinct record at a time per > thread... > > Public Class Form1 > > Private MessageArray() As MessageHandler > Private MH As MessageHandler > > Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As > System.EventArgs) Handles MyBase.Load > > MH = New MessageHandler > > Dim i As Integer > Dim iTo As Integer = 4 '4 threads > Dim iFrom As Integer = 1 > > ReDim MessageArray(iTo - iFrom) > Dim Msg As MessageHandler > For i = iFrom To iTo > Msg = New MessageHandler() > MessageArray(i - iFrom) = Msg > 'pass parameters to the new thread > Msg.i = i > Msg.MainForm = Me > Dim ts As ThreadStart > ts = New ThreadStart(AddressOf Msg.ProcessingOutboundThread) > Dim wrkThread As Thread > wrkThread = New Thread(ts) > Msg.CurrentThread = wrkThread > wrkThread.SetApartmentState(ApartmentState.STA) > wrkThread.Name = i.ToString() 'for easier tracing > wrkThread.Start() > Next > 'end start > End Sub > > End Class > > Class MessageHandler > > Public MainForm As Form1 > Public i As Integer > Public CurrentThread As Thread > Public iThreadId As Integer > Public cnString As String = > "server=servername;database=dbname;uid=username;pwd=password" > Private WithEvents Timer1 As System.Timers.Timer > > Private Sub Timer1_Elapsed(ByVal sender As Object, ByVal e As > System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed > > iThreadId = Thread.CurrentThread.GetHashCode() > > Dim cn As SqlConnection > cn = New SqlConnection(cnString) > Dim cmd As SqlCommand > Dim dtr As SqlDataReader > > Try > Try > cmd = New SqlCommand("select top 1 * from queue_table where > time_to_send=1", cn) > cn.Open() > dtr = cmd.ExecuteReader() > If dtr.HasRows() = True Then > dtr.Read() > Dim varE As String = dtr("employeetosendto") > Dim varM As String = dtr("employeemessageaddress") > dtr.Close() > cmd = New SqlCommand("update queue_table set > time_to_send=0 where employee='" & varE & "'", cn) > cmd.ExecuteNonQuery() > Call_Send_Message_Sub_Here 'call another sub pass employeemessageadress as > param > cmd = New SqlCommand("update queue_table set > sentmessage=1 where employee='" & varE & "'", cn) > cmd.ExecuteNonQuery() > end if > Catch ex As Exception > msgbox(ex.Message.ToString()) > Finally > If cn.State = ConnectionState.Open Then cn.Close() > End Try > End If > Catch ex As Exception > msgbox(ex.Message.ToString()) > Finally > If cn.State = ConnectionState.Open Then cn.Close() > End Try > End Sub > > Public Sub ProcessingOutboundThread() > Dim iThreadId As Integer > iThreadId = Thread.CurrentThread.GetHashCode() > > Timer1 = New System.Timers.Timer > Timer1.Interval = 5000 ' 5 seconds > Timer1.Start() > > Application.Run() > End Sub > End Class > > I'd appreciate any feedback on how I can make this a more threadsafe app or > more stable app. Thanks a lot. > > Jay The Elapsed event on System.Timers.Timer will run on a thread from the ThreadPool if SynchronizingObject is null. When SynchronizingObject is set to a Form or Control then the Timer will automatically marshal the Elapsed event onto the thread hosting that Form or Control. In your case the Elapsed event is running on another thread because you aren't setting the SynchronizingObject property. The thread running ProcessingOutboundThread isn't doing much. In fact, the only thing it's doing is getting a Timer started. After that it just blocks on Application.Run consuming system resources. You can just as easily get the Timer started on the main UI thread inside the Form_Load event. Better yet, set the SynchronizingObject property to Form1 and the Elapsed event will always run on the main UI thread. That will absolutely guarentee that the queries will be executed one at a time. And of course, since there wouldn't be more than one thread in play the issue of thread-safety is moot. Brian
Changing Color of Textbox on Hover
Offline application for reporting and collect data Email Socket Question Fastest String search Report Viewer Asynchronous thread abort error No Response Redirect but something like Response Forward? Disable sort on specific columns with VB.NET datagrid Find Window Question What does this mean? Error in displaying data grid |
|||||||||||||||||||||||