加一点重要线索:  如果这个Form 是 ShowDialog()出来的,则有上述问题,否则(用Show()),则没有这个问题.后来和消息循环有关. 不知 .Net里有没有可以操作消息的类.

解决方案 »

  1.   

    精简版不清楚,但是.net framework下,某个线程要修改主线程的UI,需要采用.net framewok Asynchoronas Programming Patten Model(异步编程模型),注意6 7步
    step:1  对要异步调用的方法,做一个 异步委托,如:Method_Delegate
         2  调用 Method_Delegate.BeginInvoke(asyCB,null);
         3  做 异步回调 AsynCallback asyCB;//AsynCallback(IAsyncResult)
         4  将用于结束的方法EDInvoke(IAsyncResult ar) 加入asyCB回调
         5  在EDInvoke()中写,Method_Delegate.EndInvoke(ar);
         6  下面的代码 将用于 更新主线程UI,
        MethodInvoke mi = new MethodInvoke(UpdateUI);//MethodInvoke为 void (void)委托
        this.BeginInvoke(mi);
         7   完成UpdateUI方法,以更新 UI
        private void UpdateUI()
        {
         //加入需要的代码,用于更新UI
         }
      

  2.   

    谢谢 Stevetan81。只是精简版不支持Delegate.BeginInvoke: 编译没问题,但运行时将直接抛出“Unsupport”的异常。 Control.Invoke倒是没有异常,但对我提的问题没有任何改变。依然是:后台线程无法改变前台一个模态的窗口的控件外观属性。想过用传统的win32的方法:通过消息循环来使后台线程要执行的代码,切换到前台执行。但可惜该方法在WinCE或说在精简版.net里仍不支持。有没有别的绕过去的方法? 不知大家在处理掌上设备使精简版.net 开发socket程序时,是如何解决接收时的阻塞问题? 如果和我一样用了后台线程,那上面的问题如何解决。感觉.net中有好多东西确实还有待发展,很多东西似乎只是看着可用,真用起来,文档里没说到的问题,局限,都出来了。
      

  3.   

    在精简版里面的多线程安全性做的不是很好。如果你看一下里面的il,你会发现基本上每一个属性都会要求是从创建这个控件的那个线程进行调用。按道理来说,通过Invoke应该是没有问题的,因为它会自己进入那个线程去调用。如果出现你的问题(我也没有遇到过),那么我建议你做下面这几个检查:
    1、你是通过哪个线程Show出这个窗口的。
    2、你时候已经挂起了原来的线程(执行Application.Run的那个)
    3、如果暂时没有办法解决这个问题的话,采用Show的方式将就一下。因为.NET CF的ShowDialog方式的窗口做的也很差劲。你可以通过去掉ControlBox的方法避免通过右上角关闭,同时Show了这个窗口之后把主窗口Hide。通过你设置的一个菜单或者按钮退出窗口,推出的时候先Show原来的主窗口再Hide自己。注意顺序!至于你说的Socket接受阻塞问题,我看不出来如何不能够解决,因为Socket里面有BeginReceive/EndReceive等一系列的BeginXXX/EndXXX系列。我也看过il代码,不觉的会不受支持。我没有在.NET CF下面试过这个,但是在.NET Framework下面用过,很爽,你不需要自己动脑筋建立多线程等机制,工作的非常好,基本上不会出大的差错,尤其在1.1版里面。如果你还有什么问题可以找我,或者你可以到MS的新闻组compactframework下面问问。估计整个CSDN里面也不会有几个人对.NET CF熟悉的,有时候我遇到问题了也没办法解决,最极端的就是连MS新闻组里面的MVP、eMVP、MS Support都没有办法解决,劝我用别的工具比如eVC或者用第三方控件(要$的),甚至干脆劝我放弃。TNND,只好自己摸索。用英文跟别人交流就是没有用中文交流爽,可惜CSDN里面又没有人能够解答我的问题……你比较幸福了   :P
      

  4.   

    sumtec(Psydian) ,很谢谢你的热心!
    下面回答你说的三点问题:1、窗口都是通过主线程(Application.Run所在线程)来show或showdialog出来的。如果通过其它线程,则程序会立即“卡”住,停在show()这一句。2、原来的线程没有挂起,事实上,用户还可以在前台做各种输入,当用户关闭窗口时,后台线程倒是会飞快地运行到结束。3、第三点看上去你是要避免用户在两个或更多个窗口之间切换,对吗? 其实因为我是在掌上设备上写的程序,所以无论是show()还是showdialog(),二者一般都是出来一个全屏的窗口,用户只有关了当前最前面的窗口,才能加到后面的窗口。因此主要问题不在于维护窗口的显示与隐闭,而在于程序里。运行 showdialog()时,程序会暂停,直到一个结果才继续运行后面的代码。而show呢,你知道的,程序还没有等用户关闭了,就直接运行后面代码了,可是我后面的代码依赖于用户在show出来的窗口里的最终输入结果呢。 难道我要在show之后来一个
    while(form2 is closed)
    {
      Application.DoEvent;
    }
    吗? 
    我有点晕。
    再次感谢!
      

  5.   

    我改用Forms.Timer来代替线程。解决上面问题。
    但发现UdpClient.Receive() 只能接收最大1.4k多的数据? 对方发送约2K 的数据,从防火墙看,数据已到达该端口,可是UdpClient.Recevie()却没有动静。依然堵塞着?
      

  6.   

    你实际上是要异步接收Socket数据吧?你很应该尝试使用Socket里面的BeginXXX/EndXXX系列。自己弄肯定是有很多不同的问题的。此外,我说的Show和Hide的问题,你现在用ShowDialog不会遇到,那个是Show的问题,如果你Show一个MinimizeBox==true的窗口,很容易就会混乱的,怎么个混乱法一下子也说不清楚,你多做一些打开/关闭/切换任务的动作就会发现的。
      

  7.   

    我用了 BeginXXX 和 EndXXX 了,我敢肯定,其实它只是用了 WSASocket 的线程.(在W32里,WSASock 是另开一个线程,然后通过消息将操作权切换到主线程,在.Net里,没有发消息这一过程,直接还是在后台线程里回调,这样会带来很多线程方面的问题.要安全地让后台线程改变前台的控件外观属性,除了用Control.Invoke,以外,我想我的用消息定时器来接定时接收倒是一个方便的办法.)
    总之,用了BeginXXX了,还是每次只能接收到 1.4K左右的udp数据包.我查了一个,.Net里的socket 接收缓存大小为 4k呢,可是在CE里和.net精简版里,却不能通过 SetSocketOption来修改它. 可能在Windows 2000里,会没有这问题吧.谁有试过.说说.
      

  8.   

    每次接收1.4k有什么问题吗?如果他还是可以接受下一个数据的话,你可以自己建立缓冲啊。也许你觉得这样子麻烦?事实上你自己应该是需要建立缓冲的,因为Socket的缓冲不能够区分出你定义的一个包,于是很有可能你的n次发送会一次过接收到,也可能1次发送要分n次接收。这个有时候并不是你改变Socket缓冲就能够解决的,因为数据总是一个包一个包的发出去,尤其在经过一些网关或者路由之后有可能会把你的一个包给拆开成几个,如果网络延时比较大,你就很可能分开几次收到数据。这个不仅仅在.NET CF下面会遇到,在.NET下面也一样会的。此外,.NET 里面有发送消息的能力,.NET CF也有,不过需要用反射绑定。
    .NET CF:
    Microsoft.WindowsCE.Forms.dll -> Microsoft.WindowsCE.Forms.MessageWindow -> 
    SendMessage(...)某一个窗口的句柄你需要通过反射绑定获得私有字段“_hwn”,这个就是hwnd。
      

  9.   

    我自己当然是建立缓存的...只是服务器端不是我写的程序, 服务器端一次发送最小分包为3.5
    k . 对于udp ,我收不到(一个字节都收不到,不是说能先收1.4,再接着收到3.5-1.4), 如果是一次发送1.4,我就能收到.....不过这个问题似乎是模拟器带来的,我把程序同步到实际的手持设备, 就解决了.当然,同时我也换了一台服务器,原来的那台中了冲击波....所以我不知到底只能收到1.4k,是冲击波造成,还是模拟器上的受约. 不过,中冲击波那台,出了很多事,比如要常常要重启一下,才能通讯,不然就什么反应都没有.  已经写了申请条了,公司到今天也没有派人修理...谢谢你关于如何获得 hwnd的解释!