-1

スレッドを開始すると、「Thread.Abort()」を実行しても、ThreadStateは常に「Unstarted」になります。スレッドは開始して正常に終了します...なぜ常に同じ状態になるのかわかりません。 。

Dim thread_1 As System.Threading.Thread = New Threading.Thread(AddressOf mithread)
thread_1.Start()

System.Threading.Thread.Sleep(100)

While not thread_1.ThreadState = Threading.ThreadState.Running
    MsgBox(thread_1.ThreadState.ToString) ' "Unstarted"
    thread_1.Abort()
    MsgBox(thread_1.ThreadState.ToString) ' "Unstarted" again and again...
End While

アップデート

これはスレッドを呼び出すサブであり、問​​題は「while」の状態が待機していないことです。

PS:このサブの真ん中にコメントの説明を見ることができます:

 public sub...
        ...
        If Not playerargs = Nothing Then
            If randomize.Checked = True Then
                Dim thread_1 As System.Threading.Thread = New Threading.Thread(AddressOf mithread)
                thread_1.Start()

                System.Threading.Thread.Sleep(50)
                While thread_1.ThreadState = Threading.ThreadState.Running
                    Windows.Forms.Application.DoEvents()
                End While

            Else
                progresslabel.Text = "All files added..."
            End If

            ' HERE IS THE PROBLEM, IF I CHECK "AUTOCLOSE" CHECKBOX THEN,
            ' THE FORM ALWAYS TRY TO CLOSE BEFORE THREAD IS COMPLETED:
            ' -----------------------------------------
            If autoclose.Checked = True Then Me.Close()
            '------------------------------------------
        Else
        ...
 End Sub

そして、これが「mithread」スレッドです。

Public Sub mithread()

Dim Str As String
Dim Pattern As String = ControlChars.Quote
Dim ArgsArray() As String
Str = Replace(playerargs, " " & ControlChars.Quote, "")
ArgsArray = Split(Str, Pattern)
Using objWriter As New System.IO.StreamWriter(Temp_file, False, System.Text.Encoding.UTF8)
    Dim n As Integer = 0
    Dim count As Integer = 0
    Dim foldercount As Integer = -1

    For Each folder In ArgsArray
        foldercount += 1
        If foldercount > 1 Then
            InvokeControl(ProgBarPlus1, Sub(x) x.Max = foldercount)
        End If
    Next

    If foldercount = 1 Then
        For Each folder In ArgsArray
            If Not folder = Nothing Then
                Dim di As New IO.DirectoryInfo(folder)
                Dim files As IO.FileInfo() = di.GetFiles("*")
                Dim file As IO.FileInfo
                InvokeControl(ProgBarPlus1, Sub(x) x.Max = files.Count)
                For Each file In files
                    n += 1
                    CheckPrimeNumber(n)
                    count += 1
                    If file.Extension.ToLower = ".lnk" Then
                        Dim ShotcutTarget As String = Shortcut.ResolveShortcut((file.FullName).ToString())
                        objWriter.Write(ShotcutTarget & vbCrLf)
                    Else
                        objWriter.Write(file.FullName & vbCrLf)
                    End If
                Next
            End If
        Next
    ElseIf foldercount > 1 Then
        For Each folder In ArgsArray
            If Not folder = Nothing Then
                Dim di As New IO.DirectoryInfo(folder)
                Dim files As IO.FileInfo() = di.GetFiles("*")
                Dim file As IO.FileInfo
                InvokeControl(ProgBarPlus1, Sub(x) x.Value += 1)
                For Each file In files
                    If file.Extension.ToLower = ".lnk" Then
                        Dim ShotcutTarget As String = Shortcut.ResolveShortcut((file.FullName).ToString())
                        objWriter.Write(ShotcutTarget & vbCrLf)
                    Else
                        objWriter.Write(file.FullName & vbCrLf)
                    End If
                Next
            End If
        Next
    End If
End Using

If Not thread_1.ThreadState = Threading.ThreadState.AbortRequested Then
    MsgBox(thread_1.ThreadState.ToString)
    Randomize_a_file.RandomizeFile(Temp_file)
    InvokeControl(ProgBarPlus1, Sub(x) x.Value = 0)
    '  Process.Start(userSelectedPlayerFilePath, ControlChars.Quote & Temp_file.ToString() & ControlChars.Quote)
    InvokeControl(progresslabel, Sub(x) x.Text = "All files launched...")
End If

サブ終了

4

2 に答える 2

1

スレッドの完全な開始を妨げている何かが mithread で起こっているようです。mithread の空のサブルーチンを使用して同様のコードを実行したところ、予想されるスレッド状態 (停止してから中止) が得られました。

    Sub Main()

    Dim thread_1 As System.Threading.Thread = New Threading.Thread(AddressOf mithread)
    thread_1.Start()

    System.Threading.Thread.Sleep(100)

    While Not thread_1.ThreadState = Threading.ThreadState.Running
        Console.WriteLine(thread_1.ThreadState.ToString)
        thread_1.Abort()
        Console.WriteLine(thread_1.ThreadState.ToString)
        If thread_1.ThreadState = Threading.ThreadState.Aborted Then Exit While
    End While

End Sub

Sub mithread()
End Sub
于 2012-12-21T16:51:37.593 に答える
1

あなたの問題を解決するのは簡単ではありませんが、While ループと DoEvents はまったく前進する方法ではないと言えます。

代わりに、スレッドがすべての作業を完了したときにイベントを発生させ、イベントをサブスクライブし、発生したときにフォームを閉じます (autoclose = true の場合):

Public Class Form1
Public Event threadCompleted()
Public Sub New()
    InitializeComponent()
    AddHandler threadCompleted, AddressOf Me.Thread_Completed
End Sub


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim t1 As New Threading.Thread(AddressOf mithread)
    t1.Start()
End Sub

Public Sub mithread()
    'simulate some work:
    Threading.Thread.Sleep(3000)
    'then raise the event when done
    RaiseEvent threadCompleted()
End Sub

Public Delegate Sub Thread_CompletedDelegate()
Private Sub Thread_Completed()
    If Me.InvokeRequired Then
        Me.BeginInvoke(New Thread_CompletedDelegate(AddressOf Thread_Completed))
    Else
        If autoclose.Checked = True Then
            Me.Close()
        End If
    End If
End Sub
End Class

または、これらすべてを行うバックグラウンド ワーカーを使用し、進行状況の報告とキャンセルをすべて処理します。

于 2012-12-21T18:08:04.533 に答える