【问题标题】:Async TCP Data from another thread cannot be safe. Cross-Thread Operation来自另一个线程的异步 TCP 数据不安全。跨线程操作
【发布时间】:2011-08-26 00:13:21
【问题描述】:

我有两个类库。一个是普通的 .NET 程序集,另一个是链接桌面类文件的 Compact Framework 设备程序集。该库负责服务器和客户端之间的 TCP 异步操作。

现在我为服务器创建一个 Windows 项目,并为客户端创建一个 Windows Mobile Forms 设备项目。

我在客户端和服务器接收到的数据上使用了一些事件。为了触发来自通过 TCP 安全的异步接收数据的数据,我使用了一个控制类虚拟对象来检查是否需要调用。

奇怪的是,当从服务器向设备 CF 客户端发送数据时,数据不需要任何线程处理来处理您需要显示数据的控件。 但是从客户端发送数据到服务器我得到跨线程操作异常。

这是一些代码。

我用来保护数据的静态方法。

public static void InvokeIfNecessary(Control control, Action setValue)
{
    if (control.InvokeRequired)
    {
        control.Invoke(setValue);
    }
    else
    {
        setValue();
    }
}

当我要抛出的数据来自于 TCP 通信。

    if (OnClientChangeConnection != null) SafeData.InvokeIfNecessary(_helpControl, () => OnClientChangeConnection(ConnectedClients, requestClientInfo));

知道为什么我会出现这种行为吗?或者有什么更好的方法来处理这个问题?

谢谢!

【问题讨论】:

  • 我不明白你的评论,这与我的问题完全无关。
  • 主要是。我希望你用普通的旧 c# 或 windows 或更通用的东西来标记它。我只是在看到一个看起来非常有趣的问题时感到沮丧,然后发现它出现在一个我甚至不感兴趣的平台上。
  • 基本上问题不是针对平台,而是针对 TCP 和异步。

标签: .net asynchronous c#-3.0 tcp multithreading


【解决方案1】:

由于您正在定义InvokeIfNecessary,请注意“如果需要”部分。这意味着请求可能来自与调度程序不同的线程。请注意,我说的是“可能”——这意味着它可能不会,因此可能来自调度程序。

完整框架和紧凑框架可能使用不同的线程来处理异步操作。例如,compact 框架可能是单线程的(因为它在 Mobile 上运行),而服务器完整框架可能是多线程的。 API 看起来一样,但数据可能来自不同的线程。

Silverlight 就是一个很好的例子,它使用调度程序线程(即主 UI 线程)进行网络访问和其他工作,即使您使用的是 BeginXXX/EndXXX 异步调用。因此,如果您在这个移动环境上运行简单的代码,您不会得到线程异常,但您肯定可能在服务器上得到一个,其中 BeginXXX/EndXXX 调用可能会转到不同的线程 - - 再次,他们可能不会,这实际上取决于服务器在调用时的决定。

因此,您总是需要找出请求是否来自不同的线程。使用像 InvokeIfNecessary 这样的东西是必要的,也是正确的做法——不要仅仅因为在某些环境中你看不到问题而忽略它。

【讨论】:

  • 但是,当数据来自另一个线程时,当它进入 InvokeIfNecessary 时,并且由于我在项目中引用该库,它像我使用的虚拟控件一样在同一个线程中运行,但是当数据来自另一个线程,我可以说是因为我得到了一个跨线程操作异常......当检查 InvokeIfNecessary 时,代码说不需要调用!这是怎么回事?有解决问题的想法吗?
  • 你怎么知道不需要调用?调试器?
  • 是的...如果我使用带有断点的 Visual Studio 调试器跟踪代码。
  • 好吧,我想有些调用不需要编组到调度程序线程。在 InvokeRequired 语句块内设置断点以查看它是否曾经执行过。
  • 它执行,它永远不会进入 if (control.InvokeRequired) { control.Invoke(setValue); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2016-04-19
  • 2021-11-06
  • 1970-01-01
相关资源
最近更新 更多