Electro_Attacks Ответов: 1

Как исправить исключение "bindingsource не может быть собственным источником данных"?


Я получаю в некоторых различных ситуациях недопустимую операцию Esception, говоря, что мой Bindingssource не может быть его собственным источником данных... Как я могу исправить это исключение? Он появляется, когда я начинаю новое сканирование (так что очистка Datatable с помощью
NwSdata.Clear()
)

Мой источник данных для моего Datagridview-это следующий код:
Public NwSData As DataTable = New DataTable
Public NwSBinding As BindingSource = New BindingSource

Private Sub NwS_DataSource()
        NwSData.Columns.Add("NwS_Column1", GetType(System.Drawing.Image))
        NwSData.Columns.Add("NwS_Column2", GetType(String))
        NwSData.Columns.Add("NwS_Column3", GetType(String))
        NwSData.Columns.Add("NwS_Column4", GetType(String))
        NwSData.Columns.Add("NwS_Column5", GetType(String))
        NwSData.Columns.Add("NwS_Column6", GetType(String))
        NwSBinding.DataSource = NwSdata
        NwS_Log.DataSource = NwSBinding
        NwS_Log.Columns(0).AutoSizeMode = DataGridViewAutoSizeColumnMode.None
        NwS_Log.Columns(0).HeaderText = "Status"
        NwS_Log.Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.None
        NwS_Log.Columns(1).HeaderText = "IP Address"
        NwS_Log.Columns(2).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
        NwS_Log.Columns(2).HeaderText = "Hostname"
        NwS_Log.Columns(3).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
        NwS_Log.Columns(3).HeaderText = "Mac - Address"
        NwS_Log.Columns(4).Visible = False
        NwS_Log.Columns(4).HeaderText = "Status String"
        NwS_Log.Columns(5).Visible = False
        NwS_Log.Columns(5).HeaderText = "Bytes"

        ' Put each of the columns into programmatic sort mode.
        For Each column As DataGridViewColumn In NwS_Log.Columns
            column.SortMode = DataGridViewColumnSortMode.Programmatic
        Next
    End Sub


Что я уже пробовал:

Я попытался приостановить привязку, прежде чем очистить DataTable с помощью
NwSBinding.SuspendBinding()
и возобновите его после того, как все будет сделано.
NwSBinding.ResumeBinding()

Maciej Los

Вы пытаетесь обновить BindingSource в другом потоке?

[no name]

Я обновляю DataTable с помощью Synclock из других потоков, вот почему я попытался NwSBidning.SuspendBinding()
Сам Bindingsource используется в потоке пользовательского интерфейса так же, как и Datagridview

Maciej Los

Пожалуйста, используйте виджет "ответить", чтобы быть уверенным, что система сообщит мне о вашем ответе.
Виджет "ответить" находится рядом с ником/логином.

1 Ответов

Рейтинг:
8

Maciej Los

Вам нужно использовать BeginInvoke[^] метод.

Здесь вы найдете пример кода: E813 - обновление источника данных сетки из отдельного потока | поддержка DevExpress[^]
Обратите внимание, что это связано с сеткой DevExpress, но идея та же самая.

В качестве альтернативы я бы предложил прочитать это: c# - обновление элементов в BindingSource с помощью отдельной задачи - переполнение стека[^]


[no name]

Поэтому я прочитал ссылки, которые вы упомянули, и выбрал первый метод с перезаписью события BindingSource... Поскольку код был на C#, я использовал онлайн-конвертер, чтобы получить его в vb. Но компилятор говорит, что в строке есть проблема: syncContext.Send(Function(__) MyBase.OnListChanged(e), Nothing)
Выражение не имеет значения

Вот переведенный код:

Imports System.ComponentModel
Imports System.Threading

Public Class SyncBindingSource
    Inherits BindingSource

    Private syncContext As SynchronizationContext

    Public Sub New()
        syncContext = SynchronizationContext.Current
    End Sub

    Protected Overrides Sub OnListChanged(ByVal e As ListChangedEventArgs)
        If syncContext IsNot Nothing Then
            syncContext.Send(Function(__) MyBase.OnListChanged(e), Nothing)
        Else
            MyBase.OnListChanged(e)
        End If
    End Sub
End Class

Не могли бы вы помочь мне сделать перевод?

Maciej Los

Код выглядит нормально. Что такое точное сообщение об ошибке?

[no name]

Код ошибки-BC3091, но там нет никакого сообщения, кроме "выражение не имеет значения"... Ошибка находится в строке 15, но показывает два раза...

Maciej Los

Я не могу найти такую ошибку в документации MSDN... ;(

Может быть, вы найдете здесь что-нибудь полезное: Понимание SynchronizationContext (Часть I)[^]?

[no name]

Хм, это настоящая ошибка во время отладки, я не могу запустить отладчик из-за этого xD

Maciej Los

Перейдите в окно вывода компилятора, выберите строку с сообщением об ошибке и нажмите клавишу F1.

Кстати: какая версия Visual Studio?

[no name]

Я использую Visual Studio 2019, и программа находится в vb.net v4.8 :)

[no name]

Так это на сайте Майкрософт говорят:

Вы попытались использовать выражение, которое не создает значение в контексте, создающем значение, например вызов Sub в контексте, где ожидается функция.
Код ошибки: BC30491

Чтобы исправить эту ошибку
Измените выражение на то, которое создает значение.

Есть идеи, как изменить его, чтобы он работал? :Д

Maciej Los

Ну, я бы предложил использовать делегат. Итак, создайте суб и делегата. Следуйте инструкциям из MSDN: Как вызвать метод делегата - Visual Basic | Microsoft Docs[^]

[no name]

Вызовы для меня не вариант, потому что они будут толкать процесс обратно в поток пользовательского интерфейса...

Maciej Los

Я пытаюсь сказать следующее: вы должны создать субподряд, в котором MyBase.Вызывается OnListChanged(e). Эта подлодка должна быть вызвана делегатом. ;)
Это более понятно?

[no name]

Я знаю, что вы имеете в виду, но у меня нет ни малейшего понятия о том, как это реализовать xD

Maciej Los

Попробуй:

syncContext.Send(Sub(x) MyBase.OnListChanged(e), Nothing)

[no name]

Просто глядя на ваш код мне пришла в голову идея обменяться syncContext.Send(Function(__) MyBase.OnListChanged(e), Nothing) с syncContext.Send(Sub(__) MyBase.OnListChanged(e), Nothing) в моем классе SyncBindingSource ошибка исчезла :D

Maciej Los

:) Функция должна возвращать значение. Суб - нет.
;)

[no name]

Да, я просто забыл об этом и подумал, что переводчик тоже это знает xD