【问题标题】:Task is running and cannot be finished任务正在运行,无法完成
【发布时间】:2016-08-27 03:08:14
【问题描述】:

在我的任务中出现未完成的奇怪行为。我一直在使用它,但我想它是因为我传递给它的 sub 正在与表单进行迭代 - 更改选择并刷新一些列表框可能因此它的堆栈在那里,但我不确定。让我们看看代码:

这是我想在任务中运行的子:

    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 只是一种形式(我几乎在所有需要用户等待的地方都使用它,除了这个特殊情况外它还能工作):

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

有什么问题吗?是因为程序正在与列表框和组合框交互吗?如果是这样,如何解决这个问题,我阅读了一些关于调用列表框和组合框的内容,但不知道如何解决这个问题。

编辑: 我认为除了这些行之外:

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

可能还必须调用循环。等待您的帮助。

【问题讨论】:

    标签: vb.net


    【解决方案1】:

    有一条规则说“唯一可以修改窗口中控件的线程是创建窗口的线程”。任何其他线程试图修改窗口中的内容都会产生跨线程调用异常。

    所以在你的第一次编辑中你做对了,你必须调用函数。

    但是,这并不能解决您未完成任务的问题。

    我相信 sKey.IsSelected = False 不会取消选择 ListBox 中的任何内容,因此会导致无限循环......而且 Goto 语句是非常糟糕的编程习惯,不应该使用。总有另一种解决方案可以让您的代码更易于调试/维护/阅读...

    ListBoxItem 不是 .Net Framework 中存在的类型。所以要么你创建了那个类,要么它是别的东西(我不知道是什么......)

    你可以做些什么来解决你的问题:

    1. 获取列表中所有选定项的索引
    2. 遍历您的列表,并检查是否应该选择它们:
      • 如果它们应该被选中,什么也不做
      • 如果不应该,请取消选择。

    这使您的代码像这样(并且您删除了您不希望在代码中出现的丑陋的 Label 和 Goto)...

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      相关资源
      最近更新 更多