2011-01-02 33 views
13

Tengo una aplicación de formulario ganador con un cuadro de lista que muestra los métodos (por atributo). Estoy intentando invocar dinámicamente los métodos en un hilo, usando la reflexión para obtener información del método del valor seleccionado del cuadro de lista. Sin embargo, al llamar al Methodinfo.Invoke obtengo esta excepción interna "Método no estático requiere un C# de destino".El método no estático requiere un objetivo C#

Aquí está mi código (tener en cuenta que todavía estoy nuevo en C# y la programación en general.)

private void PopulateComboBox() 
{//Populates list box by getting methods with declared attributes 
    MethodInfo[] methods = typeof(MainForm).GetMethods(); 

    MyToken token = null; 
    List<KeyValuePair<String, MethodInfo>> items = 
     new List<KeyValuePair<string, MethodInfo>>(); 

    foreach (MethodInfo method in methods) 
    { 
     token = Attribute.GetCustomAttribute(method, 
      typeof(MyToken), false) as MyToken; 
     if (token == null) 
      continue; 

     items.Add(new KeyValuePair<String, MethodInfo>(
      token.DisplayName, method)); 

    } 

    testListBox.DataSource = items; 
    testListBox.DisplayMember = "Key"; 
    testListBox.ValueMember = "Value"; 
} 

public void GetTest() 
{//The next two methods handle selected value of the listbox and invoke the method. 

    if (testListBox.InvokeRequired) 
     testListBox.BeginInvoke(new DelegateForTest(functionForTestListBox)); 
    else 
     functionForTestListBox(); 

} 

public void functionForTestListBox() 
{ 
    _t = testListBox.SelectedIndex; 

    if (_t < 0) 
     return; 

    _v = testListBox.SelectedValue; 

    method = _v as MethodInfo; 


    if (method == null) 
     return; 

    _selectedMethod = method.Name; 

    MessageBox.Show(_selectedMethod.ToString()); 

    method.Invoke(null, null);//<----Not sure about this. it runs fine when I dont invoke in a thread. 

    counter++; 

} 
private void runTestButton_Click(object sender, EventArgs e) 
{// Click event that calls the selected method in the thread 
    if (_serverStatus == "Running") 
    { 

     if (_testStatus == "Not Running") 
     { 

      // create Instance new Thread and add function 
      // which will do some work 
      try 
      { 
       SetupTestEnv(); 
       //functionForOutputTextBox(); 
       Thread UIthread = new Thread(new ThreadStart(GetTest)); 
       UIthread.Name = "UIThread"; 
       UIthread.Start(); 
       // Update test status 
       _testStatus = "Running"; 
       //Make thread global 
       _UIthread = UIthread; 
      } 
      catch 
      { 
        MessageBox.Show("There was an error at during the test setup(Note: You must install each web browser on your local machine before attempting to test on them)."); 
      } 

     } 
     else 
     { 
      MessageBox.Show("Please stop the current test before attempt to start a new one"); 
     } 
    } 
    else 
    { 
     MessageBox.Show("Please make sure the server is running"); 
    } 
} 

Respuesta

19

Usted está tratando de invocar el método no estático sin proporcionar referencia de instancia de objeto, por lo que este método debe ser invocado Puesto que usted está trabajando con métodos de MainForm clase, debe proporcionar objeto de MainForm tipo en el primer parámetro de MethodInfo.Invoke(Object, Object[]), en su caso:

if(method.IsStatic) 
    method.Invoke(null, null); 
else 
    method.Invoke(this, null); 

Ejemplo de ejecución de método en hilo separado:

public MethodInfo GetSelectedMethod() 
{ 
    var index = testListBox.SelectedIndex; 
    if (index < 0) return; 
    var value = testListBox.SelectedValue; 
    return value as MethodInfo; 
} 

private void ThreadProc(object arg) 
{ 
    var method = (MethodInfo)arg; 
    if(method.IsStatic) 
     method.Invoke(null, null) 
    else 
     method.Invoke(this, null); 
} 

private void RunThread() 
{ 
    var method = GetSelectedMethod(); 
    if(method == null) return; 
    var thread = new Thread(ThreadProc) 
    { 
     Name = "UIThread", 
    }; 
    thread.Start(method); 
} 
+0

Gracias Para la respuesta rápida. Sin embargo, después de probar este código, invoca el método seleccionado en el hilo principal, no el UIthread. (Esos nombres de hilos son ambiguos, lo siento). –

+0

Está llamando explícitamente a este método en el subproceso principal utilizando 'testListBox.BeginInvoke()'. 'MethodInfo.Invoke()' se ejecuta en el hilo desde el que se invocó. – max

+0

Ah, ya veo. Bueno, parece que tendré que replantear mi código. ¿Tiene alguna idea sobre cómo podría obtener el método seleccionado para invocar en un hilo diferente al formulario principal? –

Cuestiones relacionadas