为什么不通过内置到。net的委托调用?

时间:2022-08-27 20:47:15

I understand that .NET is multi-threaded and that is a good thing, but I continually run into issues when I have a background worker for example that is updating some control on my form and I have to do:

我知道。net是多线程的,这是一件好事,但是当我有一个后台工作人员正在更新我的表单控件时,我就会不断地遇到问题。

Private Sub SetRowCellBoolValueThreadSafe(ByVal row As Integer, ByVal col As Integer, ByVal value As Boolean)
    If dgvDatabase.InvokeRequired Then
        Dim d As New SetRowCellBoolValueCallback(AddressOf SetRowCellBoolValue)
        Me.Invoke(d, New Object() {row, col, value})
    Else
        SetRowCellBoolValue(row, col, value)
    End If
End Sub

Delegate Sub SetRowCellBoolValueCallback(ByVal row As Integer, ByVal col As Integer, ByVal value As Boolean)

Private Sub SetRowCellBoolValue(ByVal row As Integer, ByVal col As Integer, ByVal value As Boolean)
    dgvDatabase.Rows(row).Cells(col).Value = value
End Sub

My question is why is this not built into the framework - surely if I am trying to update a DataGridView it should be intelligent enough to know when the update is from another thread and it could do all the above itself?

我的问题是,为什么这不是构建在框架中——如果我试图更新一个DataGridView,它应该足够智能,能够知道何时更新来自另一个线程,并且它可以自己完成所有的任务?

3 个解决方案

#1


6  

The would mean turning every operation on a UI control into a delegate, just in case it needed to be marshalled to a different thread. That would be hugely expensive. Additionally, it presupposes that you always want to do the same thing - use Invoke rather than BeginInvoke for example.

这意味着将UI控件上的每个操作都转换为委托,以防需要将其编组到另一个线程。这将是非常昂贵的。此外,它假定您总是希望做相同的事情——例如使用Invoke而不是BeginInvoke。

I agree it's a bit of a pain in the neck to have to do this manually, but the next versions of C# and VB should make life a lot easier with async methods.

我同意手工操作有点麻烦,但是c#和VB的下一个版本应该让使用async方法更容易。

(As an aside, I don't think you really want to use ByRef for all those parameters... is it possible that you're not really clear what ByRef means?)

(顺便说一句,我认为您并不想对所有这些参数使用ByRef……)你可能不太清楚ByRef的意思吗?)

#2


1  

I don't work for Microsoft but I would guess,

我不为微软工作,但我想,

Most GUI code written with .NET is not Multi-threaded so, why incur the burden of checking for the minority case. The developer should know it there is a potential for multi-threading and check when appropriate.

大多数用。net编写的GUI代码都不是多线程的,所以为什么要承担检查少数情况的负担。开发人员应该知道多线程的潜力,并在适当的时候进行检查。

#3


1  

In the specific case of a BackgroundWorker, I would suggest you use its progress reporting feature.

对于一个背景工作者,我建议您使用它的进度报告特性。

Your BackgroundWorker calls ReportProgress, optionally passing an object with some state information. This raises the ProgressChanged event on the UI thread, which can update controls on your form, using the state information passed from the background worker.

您的BackgroundWorker调用ReportProgress,可选地传递带有一些状态信息的对象。这将在UI线程上引发ProgressChanged事件,该事件可以使用从后台worker传递的状态信息更新窗体上的控件。

Progress reporting is not limited to updating a ProgressBar or similar.

进度报告不仅限于更新进度条或类似的内容。

#1


6  

The would mean turning every operation on a UI control into a delegate, just in case it needed to be marshalled to a different thread. That would be hugely expensive. Additionally, it presupposes that you always want to do the same thing - use Invoke rather than BeginInvoke for example.

这意味着将UI控件上的每个操作都转换为委托,以防需要将其编组到另一个线程。这将是非常昂贵的。此外,它假定您总是希望做相同的事情——例如使用Invoke而不是BeginInvoke。

I agree it's a bit of a pain in the neck to have to do this manually, but the next versions of C# and VB should make life a lot easier with async methods.

我同意手工操作有点麻烦,但是c#和VB的下一个版本应该让使用async方法更容易。

(As an aside, I don't think you really want to use ByRef for all those parameters... is it possible that you're not really clear what ByRef means?)

(顺便说一句,我认为您并不想对所有这些参数使用ByRef……)你可能不太清楚ByRef的意思吗?)

#2


1  

I don't work for Microsoft but I would guess,

我不为微软工作,但我想,

Most GUI code written with .NET is not Multi-threaded so, why incur the burden of checking for the minority case. The developer should know it there is a potential for multi-threading and check when appropriate.

大多数用。net编写的GUI代码都不是多线程的,所以为什么要承担检查少数情况的负担。开发人员应该知道多线程的潜力,并在适当的时候进行检查。

#3


1  

In the specific case of a BackgroundWorker, I would suggest you use its progress reporting feature.

对于一个背景工作者,我建议您使用它的进度报告特性。

Your BackgroundWorker calls ReportProgress, optionally passing an object with some state information. This raises the ProgressChanged event on the UI thread, which can update controls on your form, using the state information passed from the background worker.

您的BackgroundWorker调用ReportProgress,可选地传递带有一些状态信息的对象。这将在UI线程上引发ProgressChanged事件,该事件可以使用从后台worker传递的状态信息更新窗体上的控件。

Progress reporting is not limited to updating a ProgressBar or similar.

进度报告不仅限于更新进度条或类似的内容。