为什么 .NET 中没有内置通过 Delegate 调用

发布于 2024-12-02 08:05:19 字数 826 浏览 0 评论 0原文

我知道 .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 ,它应该足够智能,可以知道更新何时来自另一个线程,并且它可以自己完成上述所有操作?

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:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

盛夏已如深秋| 2024-12-09 08:05:19

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

我同意手动执行此操作有点麻烦,但 C# 和 VB 的下一个版本应该会让异步方法的使用变得更加轻松。

(顺便说一句,我认为您真的不想对所有这些参数使用ByRef...您是否不太清楚ByRef 意味着什么?)

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.

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.

(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?)

时光倒影 2024-12-09 08:05:19

我不在 Microsoft 工作,但我猜想,

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

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.

山川志 2024-12-09 08:05:19

在BackgroundWorker的具体情况下,我建议您使用它的进度报告功能。

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

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

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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文