2011-01-02 25 views
13

Ho un'app per la modalità di vincita con una listbox che visualizza i metodi (per attributo). Sto tentando di richiamare dinamicamente i metodi in un thread, utilizzando la reflection per ottenere informazioni sul metodo dal valore selezionato della casella di riepilogo. Tuttavia, quando chiami Methodinfo.Invoke Ricevo questa eccezione interna "Il metodo non statico richiede un C# di destinazione".Il metodo non statico richiede un target C#

Ecco il mio codice (tenere a mente Sono ancora nuovo per C# e programmazione in generale.)

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"); 
    } 
} 

risposta

19

Si sta tentando di richiamare il metodo non statico senza fornire riferimento istanza dell'oggetto, per il quale questo metodo dovrebbe essere invocato. Dal momento che si sta lavorando con i metodi di MainForm di classe, è necessario fornire oggetto di MainForm tipo nel primo parametro di MethodInfo.Invoke(Object, Object[]), nel tuo caso:

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

Esempio di metodo di esecuzione su thread separato:

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

Grazie per la risposta rapida. Dopo aver provato questo codice, richiama il metodo selezionato sul thread mainform, non l'UIthread. (Quei nomi di thread sono ambigui, mi dispiace per quello). –

+0

Si sta chiamando esplicitamente questo metodo sul thread mainform usando 'testListBox.BeginInvoke()'. 'MethodInfo.Invoke()' esegue sul thread da cui è stato chiamato. – max

+0

Ah, capisco. Beh, sembra che dovrò ripensare il mio codice. Hai qualche idea su come posso ottenere il metodo selezionato per invocare in una discussione diversa dalla forma principale? –

Problemi correlati