Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

multithreading - 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");
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...