一直用C++,初学C#,遇到些问题请教各位。问题如下:1、主窗体类FORM1:FORM,有一个静态的方法(C#中好像习惯把函数叫方法?)和一个非静态的方法,代码大致如下。   请问在静态方法里如何调用类中的非静态方法?2、如何跨线程操作主界面的控件?/// <summary>
/// 处理事件的委托实例
/// </summary>
/// <param name="strMsg">消息内容</param>
/// <param name="socketAsync">事件</param>
/// <param name="nMsgIndex">消息代码</param>
public static void HandleMsg(string strMsg, SocketAsyncEventArgs socketAsync, int nMsgIndex)
{
    在这里出现问题:静态函数不能调用非静态函数或变量。
    ShowMsg(strMsg); // 在主窗体ListBox控件中显示消息内容
}/// <summary>
/// 显示消息
/// </summary>
/// <param name="strMsg">消息内容</param>
private void ShowMsg(string strMsg)
{
    lb_MsgInfo.Items.Add(strMsg);
    lb_MsgInfo.SelectedIndex = lb_MsgInfo.Items.Count - 1;
    lb_MsgInfo.Focus();
}

解决方案 »

  1.   

    在类里定义一个静态的Form1变量
    private static Form1 frm;Form1.frm=this;
    public static void HandleMsg(string strMsg, SocketAsyncEventArgs socketAsync, int nMsgIndex)
    {
      在这里出现问题:静态函数不能调用非静态函数或变量。
      Form1.frm.ShowMsg(strMsg); // 在主窗体ListBox控件中显示消息内容
    }
      

  2.   

    1. 不可能。除非你把类也作为参数的一部分传入静态方法中。
    2. 不可以。必须要用 Invoke 或者 BeginInvoke 把消息推到 UI 线程的消息泵上。
      

  3.   

    你好,谢谢你的回复,我刚尝试了你的方法,我也曾用过类似的方法去间接调用ShowMsg,但是执行到lb_MsgInfo.Items.Add(strMsg);这句代码时,出现以下异常:“线程间操作无效: 从不是创建控件“lb_MsgInfo”的线程访问它。”。所以我才会问第二个问题。
      

  4.   


    谢谢回复!1、在C++中也是通过类似办法间接调用的,我试试看。2、我学习C#刚一个星期,还不怎么明白异步执行委托这东西,不知道这个具体该如何做,先google一下,不行再请教你。
      

  5.   

    不可以的,静态的方法只能调用静态的方法和字段;我空间大家可以看看,希望多交流!
    hi.baidu.com/happylatch
    .
      

  6.   

    你线程里不能访问控件的,你要想线程访问控件,可以有两个方法:
    1、定义委托,然后Invoke调用线程函数,
    2、你在你程序的Sub Main入口函数里加上下面这句代码
    Control.CheckForIllegalCrossThreadCalls = false;
      

  7.   

    把函数 private void ShowMsg(string strMsg)
    改为 private static void ShowMsg(string strMsg)
    即可。
      

  8.   


    在VC中,可以通过PostMessage发送消息给界面线程,让界面线程响应该消息,对界面进行相应操作。我琢磨了一下,你说的方法和VC中的做法原理应该是一样的。
      

  9.   

    第一个,不可以,静态的只能用静态的
    第二个,有两种方式,使用invoke:
     if (InvokeRequired)
      {
      BeginInvoke(new StartSaveDataDel(StartSaveDatas));
      return;
      }
      。具体操作
    或者,直接在构造函数了添加一句
    Control.CheckForIllegalCrossThreadCalls = false;
      

  10.   


    你说的方法是这样吗?new FORM1().ShowMsg(strMsg); // 在主窗体ListBox控件中显示消息内容我这样做,编译没有错,但是界面不显示任何内容。
      

  11.   

    上面的StartSaveDataDel是一个委托,StartSaveDatas是方法名
      

  12.   


    刚尝试了,添加Control.CheckForIllegalCrossThreadCalls = false;的方法可以实现。但是这样,是否会造成线程不安全?
      

  13.   


    C# 根本就是 C++ 的一个漂亮封装而已。ps: delegate 无限接近于 Function Pointer,这样想会更容易理解 Invoke
      

  14.   


    MSDNControl..::.CheckForIllegalCrossThreadCalls Property Gets or sets a value indicating whether to catch calls on the wrong thread that access a control's Handle property when an application is being debugged............
    ............Note that illegal cross-thread calls will always raise an exception when an application is started outside the debugger.
      

  15.   

    静态方法调用非静态方法,换个思维,不知是否合适,请朋友指正:
    Class A
    {
      public static void X()
      {
        A a = new A();
        a.Y();
      }
      public void Y()
      {
        ......
      }
    }
      

  16.   


    使用异步执行委托方式已经解决问题。谢谢各位指导!另问:BeginInvoke 以后没有执行 EndInvoke 会出现什么问题?
      

  17.   

            static void Main(string[] args)
            {
                Program pg = new Program();
                pg.check();
                check2();
                Console.ReadLine();
            }
            public static void check2()
            {
                show();
            }
            public void check()
            {
                show();
            }
            public static void show()
            {
                Console.WriteLine("非静态方法和静太方法都可以调用非静态方法!");
            }
      

  18.   

    Console.WriteLine("非静态方法和静太方法都可以调用静态方法!");
      

  19.   

    c#不太了解,C++里,开线程,处理函数是类成员函数需要声明为静态,要调用类中非静态变量和函数时,是以参数形式传入指针,用指针调用。常传this。C#应该也可以类似,传个对象,对象的引用,
      

  20.   


    不怎么样,EndInvoke只是为了知道是否调用完成,控制程序运行序列的。
      

  21.   

    你的ShowMsg中的lb_MsgInfo应该是个listBox吧,把listBox也作为你的静态方法中的一个参数:public static void HandleMsg(string strMsg, SocketAsyncEventArgs socketAsync, int nMsgIndex,listBox lb)
    {
        lb.Items.Add(strMsg);
    }