C# 为什么不是';t通过内置在.NET中的委托调用

C# 为什么不是';t通过内置在.NET中的委托调用,c#,.net,vb.net,delegates,invoke,C#,.net,Vb.net,Delegates,Invoke,我知道.NET是多线程的,这是一件好事,但当我有一个后台工作人员(例如,正在更新表单上的某些控件)时,我会不断遇到问题,我必须执行以下操作: Private Sub SetRowCellBoolValueThreadSafe(ByVal row As Integer, ByVal col As Integer, ByVal value As Boolean) If dgvDatabase.InvokeRequired Then Dim d As New SetRowCel

我知道.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
我的问题是,为什么不将其内置到框架中?当然,如果我试图更新一个
DataGridView
,它应该足够智能,可以知道何时更新来自另一个线程,并且它可以自己完成上述所有工作?

这意味着将UI控件上的每个操作都转换为委托,以防它需要被封送到不同的线程。那将是非常昂贵的。此外,它假定您总是想做同样的事情,例如使用
Invoke
而不是
BeginInvoke

我同意必须手动完成这项工作有点让人头疼,但是C#和VB的下一个版本应该会让异步方法的使用变得更容易


(顺便说一句,我不认为你真的想对所有这些参数使用
ByRef
…你是否真的不清楚
ByRef
是什么意思?

我不为微软工作,但我想


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

对于后台工作人员的特定情况,我建议您使用其进度报告功能

您的BackgroundWorker调用
ReportProgress
,可以选择传递带有某些状态信息的对象。这会在UI线程上引发
ProgressChanged
事件,该事件可以使用后台工作程序传递的状态信息更新窗体上的控件


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

是否很难确定调用实际上来自另一个线程,并且只有该线程传递给代理?+1作为旁注。到处使用
ByRef
肯定很痛苦。@Tigran:这并不难,但你需要代码来到处构建代理。如果你的工作假设只有UI线程才能接触控件,那么很难想象如果没有大量粗糙(即使生成)的代码,你怎么能保持这么便宜。@Jon:我想的是编译器注入的代码,而不是像程序员一样由我生成的代码。我的意思是,即使编译器必须注入一些复杂的代码,并且不会对我的应用程序的最终性能产生太大的影响,它也会让我的代码保持清晰,而不需要对委托或其他任何调用,并继续在多线程环境中工作。当然,从这个角度来看,“异步”将使生活变得更加简单。@Tigran:这使得语言更加复杂,并且它可能会显著影响最终的性能。UI代码的每一位都会大得多,影响缓存一致性、内联等。