Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-static method requires a target C#

I have a win form app with a listbox displaying methods (by attribute). I am attempting to dynamically invoke methods in a thread, using reflection to get method info from the selected value of the the list box. However, when calling Methodinfo.Invoke I am getting this inner exception "Non-static method requires a target C#".

Here's my code (keep in mind I'm still new to c# and programming in 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");
    }
}
like image 515
prison-mike Avatar asked Jan 02 '11 04:01

prison-mike


1 Answers

You are trying to invoke non-static method without providing object instance reference, for which this method should be invoked. Since you are working with methods of MainForm class, you should provide object of MainForm type in the first parameter of MethodInfo.Invoke(Object, Object[]), in your case:

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

Example of executing method on separate thread:

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);
}
like image 119
max Avatar answered Sep 23 '22 01:09

max