请先参考
http://www.csdn.net/expert/topic/885/885033.xml?temp=.8302881
解决方案还得有空做个试验才行。

解决方案 »

  1.   

    谢谢 Latitude(Henry) 
    但是怎么解决呢?
      

  2.   

    不是太清楚。因为空闲期控制权已经交给系统了,根据sumtec的测试,现在唯一担心的就是这不要是.net的bug就好。怎么解决,还在考虑中……(现在工作有点忙,只能稍后再考虑了。抱歉)
      

  3.   

    典型的COM控件线程问题:)。如果我没猜错的话,你应该是在一个线程里创建了控件对象(一般来说是UI主线程),而到另外的线程(比如ThreadPool中的线程)中访问这个组件的方法。一般情况下Windows控件都是STA的,不支持多线程直接访问,需要相应的Marshal。在.NET里这种限制仍然存在,而.NET提供的相应的解决方法就是Control的Invoke/BeginInvoke/EndInvoke方法。这些方法可以确保最终的方法调用一定发生在创建控件的线程里。比如说,在你的例子里,如果工作线程(不是创建Control的线程)需要调用Control的Foo方法,那么它不能直接调用obj.Foo(...);而是应该生成一个Foo的delegate,然后用obj.Invoke(...);来调用。函数的使用可以参见MSDN。
    另外一个具体的例子参见
    http://www.csdn.net/expert/topic/895/895649.xml?temp=7.825869E-02
      

  4.   

    谢谢你对我的问题的回复!
    问题正如你所说的,我看了你的解决方法,但是我用的是AxMSCommLib.AxMSComm的Output,Input两个属性(Property),而Delegate只能用于Sub和Function,怎么解决呢?
      

  5.   

    property说到底也是method,一个get_一个set_,当然也可以用delegate来调用这两个方法,只不过麻烦一点(C#不允许直接引用set/get形式的函数,VB.NET应该也是)。下面是C#调用get/set访问property的一个例子,应该不难改写成VB.NET形式:
    using System;
    using System.Reflection;namespace MChen.LearnCSharp.Delegate {
    public delegate void SetValue(int val);
    public delegate int GetValue();

    public class MainClass {
    private int _val;
    public int Value {
    get { return _val; }
    set { _val = value; }
    }

    public static void Main() {
    MainClass mc = new MainClass();  SetValue sdel = (SetValue)MulticastDelegate.CreateDelegate(typeof(SetValue), mc, "set_Value");
    sdel(5); //set_value

    GetValue gdel = (GetValue)MulticastDelegate.CreateDelegate(typeof(GetValue), mc, "get_Value");
    int ret = gdel();  //get_value
    System.Console.WriteLine(ret);
    }
    }
    }
      

  6.   

    还是不明白,不知道怎么写.那个程序原来是用VB6写的,用MSCOMM控件通过串口通讯,后来由于需要支持多个串口,又要求速度,就改成VB.NET用多线程控制通讯.
    MSCOMM控件有一个OUTPUT属性,用于我们发命令和数据,有个INPUT属性用于读返回的信息,这两个属性是在控件里的,我们没有办法改它.
    看你的C#程序,好像要自己写属性的,也就是说自己能控制这个属性的代码,不知道我理解的对不对.
      

  7.   

    请 qqchen79(知秋一叶) 在帮我一下,请到一下帖子留个记号,好给分:
    http://www.csdn.net/expert/topic/903/903896.xml?temp=.6861536
      

  8.   

    不是修改属性,而是通过delegate访问属性。
    通过引用COM组件(或者使用tlbimp),你的Output在VB.NET里面应该是这样用的吧?
    MSCOMM comm = New MSCOMM()
    comm.Output = 1 '这里实际上是调用了set_Output函数那么只要能够把comm.Output = 1转换成一个delegate的调用就可以使用:
    comm.Invoke(delegate)
    从而避免线程问题了。.NET里面属性其实是有一对get/set函数组成的,比如Output,实际上是个函数:
    Sub set_Output(value as System.Int32) '只写而delegate实际上是用于包装函数的,那么只要生成get/set函数的delegate问题就解决了。问题是C#/VB.NET不允许直接以函数的形式访问属性,所以我在上面使用了MulticastDelegate.CreateDelegate绕过这些限制。SetValue sdel = (SetValue)MulticastDelegate.CreateDelegate(typeof(SetValue), mc, "set_Value");
    这一句实际上生成了一个用于为某个属性(mc.Value)符值的delegate,如果把这个属性换成comm.Output,你就可以用comm.Invoke(sdel)来安全的访问它了。
      

  9.   

    已经用其他方法解决,还是非常感谢 qqchen79(知秋一叶) 不厌其繁的解答,可能我太苯,还是没有按你的方法给试出来,也感谢其他朋友的参与。
      

  10.   

    请 大家到以下帖子留个记号,好给分:
    http://www.csdn.net/expert/topic/903/903896.xml?temp=.6861536