小编ttt*_*ttt的帖子

套接字/线程问题:撤消操作遇到的上下文与相应的Set操作中应用的上下文不同

我遇到了上述问题很多的问题.我们有一个TCP/IP服务器应用程序,已经运行了好几年.我现在需要允许应用程序接受来自直接连接的USB设备的连接,通过内部使用套接字连接来修补服务器应用程序中的localhost(127.0.0.1).(顺便说一句,我只提到USB来解释我为什么这样做 - 我禁用所有USB功能作为调试此问题的一部分).

沿此套接字的通信可导致在客户端和服务器端调用GUI元素.访问客户端上的GUI元素会导致标题中的错误(下面的调用堆栈).这里的一个关键问题是调试器无法暂停异常:尽管在抛出时将所有异常设置为暂停,但应用程序只是在发生错误时终止.

我的应用程序唯一看起来独一无二的是它使用内部套接字连接到127.0.0.1.我还确认,如果将客户端分成单独的应用程序,该应用程序可以正常工作.但是,出于其他原因,我无法将其用作永久解决方案.

有几篇帖子讨论了我在下面列出的这类问题.不幸的是,在我的案例中似乎没有提供解决方案:

  • 大多数相关帖子讨论了通过使用Invoke或BeginInvoke确保在GUI线程上执行所有GUI操作的需要.我相信我的应用程序正确执行此操作(它使用Application.Forms获取表单以获取主窗体并在此调用Invoke)并在调试器中进行了双重检查.
  • 关于上面的内容,有一些关于使用Invoke vs BeginInvoke来阻止/不阻止的讨论.在我的情况下,两者都有相同的结果.
  • 一些帖子建议有必要在GUI线程上自己创建套接字(我的).
  • 这个解释说,如果在应用程序中使用DoEvents,则可以得到错误(我没有).
  • 也意味着当使用异步调用进行客户端套接字连接时(我的客户端连接是同步的),您可能会在缺少EndConnect调用时收到错误.
  • 这个解释说,如果尚未创建窗口句柄,则可以从InvokeRequired获取不正确的结果(已使用IsHandleCreated进行了检查).
  • 微软连接上的这个报告了一个类似的声音错误,但没有解决方案(微软自2006年以来一直在'调查'它!)
  • 这个包含一个建议,使用AsyncOperationManager.SynchronizationContext来备份/恢复同步上下文,这(不出所料?)只会导致不同的错误.
  • 有几篇帖子暗示错误只是调试,以下内容会让它消失 - 但我没有费心去尝试:
    System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false

还有其他帖子提出类似的问题:这里,这里这里.这里也是一个好人.

这是一个代码片段 - 当客户端收到套接字数据时,这会导致ProcessCommandCT内的崩溃:

' Find application main form from any thread
' There is only one instance of 'RibbonForm1' and this is the main form
Public Function GetRibbonForm() As RibbonForm1
    Dim rf As RibbonForm1 = Nothing
    For Each f As Form In My.Application.OpenForms
        rf …
Run Code Online (Sandbox Code Playgroud)

.net sockets multithreading invalidoperationexception thread-safety

8
推荐指数
1
解决办法
4841
查看次数

如果您通过一次调用中的套接字向send()发送数据,是否会在一次调用中接收到receive()?

我已经看到了套接字的几种用法,程序员通过TCP/IP套接字发送命令或一些信息,并期望在接收端的一次调用中接收它.

例如,传输

mySocket.Send("SomeSpecificCommand")
Run Code Online (Sandbox Code Playgroud)

他们假设接收方将在一次通话中接收所有数据.例如:

Dim data(255) As Byte   
Dim nReceived As Long = s.Receive(data, 0, data.Count, SocketFlags.None)
Dim str As String = Encoding.ASCII.GetString(data, 0, n)
If str = "SomeSpecificCommand" Then
    DoStuff()
    ...
Run Code Online (Sandbox Code Playgroud)

上面的示例不使用任何终结符,因此程序员依赖于不允许套接字实现的事实,例如,在第一次调用Receive()时返回"SomeSpecif",并在稍后返回"cCommand"致电Receive().(注意 - 在示例中,缓冲区的大小应大于预期的字符串).

我从来没有考虑过这么多想法,只是假设这种类型的编码是不安全的,并且总是使用分隔符.我是否在浪费时间(和处理器周期)?

sockets

2
推荐指数
1
解决办法
707
查看次数