2016-05-02 13 views
4

終了していないタスクで奇妙な動作が発生しました。私はこれをずっと使用していますが、私はそれを渡しているのでフォームを変更する選択とリストボックスをリフレッシュすることになるので、おそらくそのスタックがそこにありますが、わかりません。タスクが実行中で終了できません

これは私がタスクで実行させたいサブです:

Public Sub UnselectExistingConnectionsItems() 
     Dim SentenceId, SubSubKategorieId, SubSectionId As Integer 
     SubSectionId = CbSubSections.SelectedValue 'combobox 
     If WithSubSubkategorie = SubSubKategorieEnum.Without Then 
      SubSubKategorieId = 0 
     Else 
      SubSubKategorieId = CbSubSubKategorie.SelectedValue 'combobox 
     End If 
Unselect: 
     For i As Integer = 0 To LB_Sentences.SelectedItems.Count - 1 
      Dim sKey As ListBoxItem 
      sKey = LB_Sentences.SelectedItems(i) 
      SentenceId = HtmlDescription.HtmlSentence.GetSentenceIdByName(sKey.Text) 
      If HtmlDescription.HtmlSubSubSections_Sentences.CheckIfConnectionAlreadyExist(SentenceId, SubSectionId, SubSubKategorieId) Then 
       sKey.IsSelected = False 
       LB_Sentences.Refresh() 
       GoTo Unselect 
      End If 
     Next 
    End Sub 

私はこのようなタスクにそれを置く:

Dim pic As New FrmCircularProgress(eCircularProgressType.Line) 
Dim work As Task = Task.Factory.StartNew(Sub() 
'--Run lenghty task             UnselectExistingConnectionsItems() 
'--Close form once done (on GUI thread) 
pic.Invoke(New Action(Sub() pic.StopCircular())) 
pic.Invoke(New Action(Sub() pic.Close())) 
End Sub) 

'--Show the form 
pic.ShowDialog() 
Task.WaitAll(work) 

とFrmCircularProgressがちょうどフォーム(iはコードを見てみましょう私はこのparticuralケース以外にも、ユーザーの待ち時間とその作業に持っている場合)、ほぼどこにでもそれを使用する:

何共同
Public Class FrmCircularProgress 
    Sub New(progressType As DevComponents.DotNetBar.eCircularProgressType) 
     InitializeComponent() 
     CircularProgress1.ProgressBarType = progressType 
     StartCircular() 
    End Sub 

    Public Sub StartCircular() 
     Me.CircularProgress1.IsRunning = True 
    End Sub 

    Public Sub StopCircular() 
     Me.CircularProgress1.IsRunning = False 
    End Sub 
End Class 

uldが間違っている?プロシージャはリストボックスやコンボボックスと対話しているからですか?それを修正する方法があれば、リストボックスとコンボボックスを呼び出す方法を読んでいますが、それを修正する方法はわかりません。

EDIT: は、私はこれらの線以外に思う:

sKey.IsSelected = False 
       LB_Sentences.Refresh() 

が、私はそれらを行う必要があります。

LB_Sentences.Invoke(Sub() sKey.IsSelected = False 
       End Sub) 
LB_Sentences.Invoke(Sub()                 LB_Sentences.Refresh() 
    End Sub) 

私は切り抜いたスレッドでだから。どういうわけかそれらの行を変換する方法はわかりません:

SubSectionId = CbSubSections.SelectedValue 
    SubSubKategorieId = CbSubSubKategorie.SelectedValue 

おそらくループも呼び出される必要があります。あなたの助けを待っている。

答えて

0

「ウィンドウ内のコントロールを変更できるスレッドは、そのウィンドウを作成したスレッドだけです」というルールがあります。ウィンドウ内の何かを変更しようとする他のスレッドは、クロススレッド呼び出し例外を生成します。

最初の編集では正しく機能しています。機能を呼び出す必要があります。

ただし、これでタスクを終了しないという問題は解決しません。

私はsKey.IsSelected = Falseを実行すると、ListBox内の何かが選択解除されないため、無限ループが発生すると信じています... Gotoという文は非常にプログラミング習慣が悪く、使用しないでください。あなたのコードをデバッグ/保守/読み込みが容易にする別の解決策が常にあります...

ListBoxItemは.Net Frameworkに存在するタイプではありません。だから、(...と私は何を知っていない)、あなたはどちらか、そのクラスを作成し、それは何か別のものだいずれか

あなたの問題を解決するために何ができるかです:

  1. は、内のすべての選択した項目のインデックスを取得します。あなたのリストをリスト
  2. を実行し、それらが選択されなければならないかどうかを確認:
    • 、彼らが選択しなければならない場合、彼らは、彼らの選択を解除する必要がない場合は何も
    • もしません。このようにあなたのコードになります(そして、あなたがあなたのコードにしたくないという醜いラベルと後藤を削除)

...

Public Sub UnselectExistingConnectionsItems() 
    Dim SentenceId, SubSubKategorieId, SubSectionId As Integer 
    SubSectionId = CbSubSections.SelectedValue 'combobox 
    If WithSubSubkategorie = SubSubKategorieEnum.Without Then 
     SubSubKategorieId = 0 
    Else 
     SubSubKategorieId = CbSubSubKategorie.SelectedValue 'combobox 
    End If 

    'We create an array to remind our initial selection 
    Dim sel = New Integer(LB_Sentences.SelectedItems.Count - 1) {} 
    LB_Sentences.SelectedIndices.CopyTo(sel, 0) 

    For i = 0 To sel.Length - 1 
     Dim sKey As ListBoxItem 
     'We get our selected item 
     sKey = LB_Sentences(sel(i)) 
     SentenceId = HtmlDescription.HtmlSentence.GetSentenceIdByName(sKey.Text) 
     If HtmlDescription.HtmlSubSubSections_Sentences.CheckIfConnectionAlreadyExist(SentenceId, SubSectionId, SubSubKategorieId) Then 
      'We must remove it from the selection 
      LB_Sentences.Invoke(Sub() LB_Sentences.SelectedItems.Remove(sKey)) 
     End If 
    Next 
    'We do the Refresh at the end so we gain some process time... 
    LB_Sentences.Invoke(Sub() LB_Sentences.Refresh()) 
End Sub 
関連する問題