同步线程会禁用我的应用程序工具 [英] Synchronizing Threads disables my application's tools
问题描述
我正在使用同步线程,但是当线程启动时我无法点击我的应用程序上的anthing ...但我需要在应用程序上做一些工作,即使线程计时器已打开,所以怎么能我这样做了吗?
请注意我在vs 2010上使用vb.net
这里是我的代码:
私人 共享线程作为 新 System.Threading.AutoResetEvent( False )
私有 Sub start_btn_Click( sender As System。 Object ,e As System.EventArgs)句柄 start_btn.Click
StartTask()
结束 Sub
Sub StartTask()
Dim Tpool As System.Threading.ThreadPool
Dim arg 作为 字符串 = SomeArg
ThreadPool.QueueUserWorkItem( New System.Threading.WaitCallback(_
AddressOf 任务),arg)' 将任务排队。
thread.WaitOne( )' 等待线程调用Set。
writeMsg( 线程完成。 at, list_rpt)
StartTask()
结束 Sub
Sub 任务( ByVal Arg 作为 对象)
writeMsg( 线程从, list_rpt)
System.Threading.Thread.Sleep( 4000 )' 等待4秒。
DoWork()
结束 Sub
公开 Sub DoWork()
MTProcessTable = selectMtProcess()
mtCount = MTProcessTable.Row s.Count
writeMsg(mtCount& 在, <中选择的行span class =code-string> list_rpt)
对于 每个 row 作为 DataRow 在 MTProcessTable.Rows
process = 新 Process_class
process.id = row( mt_id)
process.mo = row( mt_mo)
流程.mt = row( mt_mt)
process.datain = row( mt_datain)
keyid = validateKey(process.datain)
MOTable = selectMO(process.mo,process.mt)
moRowNb = MOTable.Rows.Count()
MO = 新 MO_class
如果 moRowNb< ;> 0 然后
MOrow = MOTable.Rows( 0 )
MO.newuser = MOrow( newuser)
MO.sim_id = MOrow( sim_id)
结束 如果
尝试
选择 案例 keyid
案例 1
如果 moRowNb = 0 然后
如果 insertMO(process.mo,process.mt)然后
writeMsg( 1 MO插入/更新为, rpt_txt)
message = msgTable.Rows( 0 )( 1 )。ToString()
MsgBox(消息)
否则
writeMsg ( 1 MO无法插入, rpt_txt)
结束 如果
结束 如果
案例 2
如果 moRowNb = 0 那么
writeMsg( 1进程,MO未激活,数据'是',, rpt_txt)
message = msgTable.Rows( 7 )( 1 )。ToString()
MsgBox(消息)
结束 如果
Catch ex As 异常
logFile( executeTimer ----& ex.Message)
updateProcessed(process.id,ex.Message, 10 )
最后
updateProcessed(process.id,message, 1 )
结束 尝试
下一步行
thread。设置()
结束 Sub
不要这样做:
ThreadPool.QueueUserWorkItem(新 System.Threading.WaitCallback(_
AddressOf 任务),arg) ' 将任务排队。
thread.WaitOne()' 等待线程进行校准l设置。
要生成一个新线程,然后立即等待该线程在启动它的线程上完成它就像没有线程一样所有。您也可以在按钮点击事件中完成任务
中的所有工作。
您想要线程做它的工作然后通知回启动它的线程(可能在工作完成时通知状态更新)。
你是什么在您的应用程序中执行的是UI线程上的WaitOne
,如果这样做,您的UI将锁定直到通知事件,这很糟糕。
如果您刚开始使用多线程应用程序,请查看使用BackgroundWorker
,这些事件可以挂钩到完成状态更新和任务完成时的报告。
这样的事可能对你有用:
Imports System.Threading
Imports System.ComponentModel
Public Class Form1
Private Sub startButton_Click(sender As System.Object,e As System.EventArgs)处理startButton。社区法网k
Dim worker As New BackgroundWorker()
worker.WorkerSupportsCancellation = True
worker.WorkerReportsProgress = True
AddHandler worker.DoWork,AddressOf MyLongRunningOperation
AddHandler worker.ProgressChanged,AddressOf MyProgressUpdate
AddHandler worker.RunWorkerCompleted,AddressOf MyWorkHereIsDone
worker.RunWorkerAsync()
End Sub
Sub MyLongRunningOperation (sender As Object,e As DoWorkEventArgs)
Dim worker As BackgroundWorker = CType(sender,BackgroundWorker)
For i = 0 To 10
if worker.CancellationPending Then
e.Cancel = True
退出
结束如果
'做你的工作
Thread.Sleep(1000)
worker.ReportProgress(i * 10)
Next
End Sub
Private Sub MyProgressUpdate(ByVal sender A s Object,ByVal e As ProgressChangedEventArgs)
progressBar.Value = e.ProgressPercentage
statusText.Text = e.ProgressPercentage& %complete
End Sub
Private Sub MyWorkHereIsDone(ByVal sender As Object,ByVal e As RunWorkerCompletedEventArgs)
如果e.Cancelled = True则
completedText.Text =操作被取消了!
ElseIf e.Error IsNot Nothing然后
completedText.Text =操作失败:& e.Error.Message
否则
completedText.Text =我已经完成了!
结束如果
结束子
结束等级
它依赖于progressBar
,statusText
和completedText
在您的表单上。我没有连接取消按钮,但我认为应该是自我解释。
希望这会有所帮助,
Fredrik
i'm using Synchronizing Threads but when the thread is starting i'm not able to click on anthing on my application... but i need to do some work on the app even if the thread timer is on so how can i do that?
note that i'm using vb.net on vs 2010
here is my code:
Private Shared thread As New System.Threading.AutoResetEvent(False)
Private Sub start_btn_Click(sender As System.Object, e As System.EventArgs) Handles start_btn.Click
StartTask()
End Sub
Sub StartTask()
Dim Tpool As System.Threading.ThreadPool
Dim arg As String = "SomeArg"
ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback( _
AddressOf Task), arg) ' Queue a task.
thread.WaitOne() ' Wait for the thread to call Set.
writeMsg("Thread is done. at ", "list_rpt")
StartTask()
End Sub
Sub Task(ByVal Arg As Object)
writeMsg("Thread is starting at ", "list_rpt")
System.Threading.Thread.Sleep(4000) ' Wait 4 seconds.
DoWork()
End Sub
Public Sub DoWork()
MTProcessTable = selectMtProcess()
mtCount = MTProcessTable.Rows.Count
writeMsg(mtCount & " rows selected at ", "list_rpt")
For Each row As DataRow In MTProcessTable.Rows
process = New Process_class
process.id = row("mt_id")
process.mo = row("mt_mo")
process.mt = row("mt_mt")
process.datain = row("mt_datain")
keyid = validateKey(process.datain)
MOTable = selectMO(process.mo, process.mt)
moRowNb = MOTable.Rows.Count()
MO = New MO_class
If moRowNb <> 0 Then
MOrow = MOTable.Rows(0)
MO.newuser = MOrow("newuser")
MO.sim_id = MOrow("sim_id")
End If
Try
Select Case keyid
Case 1
If moRowNb = 0 Then
If insertMO(process.mo, process.mt) Then
writeMsg("1 MO inserted/updated at ", "rpt_txt")
message = msgTable.Rows(0)(1).ToString()
MsgBox(message)
Else
writeMsg("1 MO could not be inserted at ", "rpt_txt")
End If
End if
Case 2
If moRowNb = 0 Then
writeMsg("1 process with MO not active and datain 'yes' at ", "rpt_txt")
message = msgTable.Rows(7)(1).ToString()
MsgBox(message)
End if
Catch ex As Exception
logFile("executeTimer ----" & ex.Message)
updateProcessed(process.id, ex.Message, 10)
Finally
updateProcessed(process.id, message, 1)
End Try
Next row
thread.Set()
End Sub
Don't do things like this:
ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback( _ AddressOf Task), arg) ' Queue a task. thread.WaitOne() ' Wait for the thread to call Set.
To spawn a new thread and then immediately wait for that thread to finish on the thread that started it is the same as not threading it at all. You might as well do all of the work inTask
in the button click event.
You want the thread to do it's work and then notify back to the thread that started it (possibly with status updates being notified back as the work is being done).
What you're doing in your application is aWaitOne
on the UI thread, if you do that your UI will lock until the event is notified, this is bad.
If you're just starting out with multithreading your application, look into using theBackgroundWorker
, that comes with events that you can hook into to do things like status updates and report when task is completed.
Something like this might work for you:
Imports System.Threading Imports System.ComponentModel Public Class Form1 Private Sub startButton_Click(sender As System.Object, e As System.EventArgs) Handles startButton.Click Dim worker As New BackgroundWorker() worker.WorkerSupportsCancellation = True worker.WorkerReportsProgress = True AddHandler worker.DoWork, AddressOf MyLongRunningOperation AddHandler worker.ProgressChanged, AddressOf MyProgressUpdate AddHandler worker.RunWorkerCompleted, AddressOf MyWorkHereIsDone worker.RunWorkerAsync() End Sub Sub MyLongRunningOperation(sender As Object, e As DoWorkEventArgs) Dim worker As BackgroundWorker = CType(sender, BackgroundWorker) For i = 0 To 10 If worker.CancellationPending Then e.Cancel = True Exit For End If ' Do your work Thread.Sleep(1000) worker.ReportProgress(i * 10) Next End Sub Private Sub MyProgressUpdate(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) progressBar.Value = e.ProgressPercentage statusText.Text = e.ProgressPercentage & "% complete" End Sub Private Sub MyWorkHereIsDone(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) If e.Cancelled = True Then completedText.Text = "Operation was cancelled!" ElseIf e.Error IsNot Nothing Then completedText.Text = "Operation failed: " & e.Error.Message Else completedText.Text = "I am all done!" End If End Sub End Class
It relies onprogressBar
,statusText
andcompletedText
being on your form. I haven't wired up a cancel button but that should be self explanatory I think.
Hope this helps,
Fredrik
这篇关于同步线程会禁用我的应用程序工具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!