Вызов методов, выбранных в ListBox - PullRequest
1 голос
/ 06 января 2012

У меня проблема с приложением Windows Forms, которое я создаю.Приложение должно быть приложением для тестирования интеграции.По сути, он должен проверить методы, которые используют множество веб-служб в одном из моих классов.Я загружаю методы из класса, который я хочу проверить с помощью отражения, и делаю это так:

private List<string> GetMethods(Type type)
{
    return (from method in type.GetMethods() where method.IsPublic &&
        method.ReturnType == typeof(void) select method.Name).ToList();
}

Возвращает список методов из этого класса, которые были созданы для тестирования веб-сервисов.и помещает их в ListBox, где пользователь может выбрать столько методов, сколько ему нравится.Мое замешательство приходит сюда.То, что я хотел бы сделать, это получить методы, выбранные пользователем, и выполнить соответствующий метод X количество раз (есть текстовое поле для ввода количества раз, чтобы выполнить метод также в форме).Я не могу понять, как выполнить эти методы, основываясь на названии метода, который я получил путем отражения.Я пробовал что-то подобное, но я знаю, что это неправильно:

private void RunMethods(Type type)
{
    var tester = new ClassToTest();
    foreach(var item in lstMethodList.SelectedItems)
    {
        foreach(var method in type.GetMethods())
        {
            if(String.Equals(item.ToString(), method.Name))
            {
                ThreadStart ts = new ThreadStart(method.Name);
                Thread thread1 = new Thread(ts);
                thread1.Start();
            }
         }
     }
}

Это даже не скомпилируется, поскольку ThreadStart требует имя метода в качестве параметра.Есть ли способ, которым это возможно сделать?Возможно, я логически ошибаюсь, но я бы хотел создать поток для каждого метода, который нужно запустить, и выполнить этот метод, сколько бы раз пользователь не указал.Предполагается, что это будет способ проведения интеграционного тестирования с некоторым нагрузочным тестированием, чтобы увидеть, что может обработать веб-служба.

Ответы [ 3 ]

1 голос
/ 06 января 2012

Вы можете использовать что-то вроде этого, чтобы получить нужные вам методы:

private List<MethodInfo> GetMethods(Type type)
{
        return (from method in type.GetMethods()
                where method.IsPublic &&
                    method.ReturnType == typeof(void)
                select method).ToList();
}

Тогда, если вы хотите вызывать методы в отдельных потоках, вы напишите (будет работать, только если методы являются статическими):

foreach(MethodInfo mi in GetMethods(SomeType) {
   MethodInfo tempMi = mi;
   Action myAction = (Action) Delegate.CreateDelegate(typeof(Action), tempMi);
   ThreadStart ts = new ThreadStart(myAction);
   Thread thread1 = new Thread(ts);
   thread1.Start();
}

Или вы бы написали (только если методы не имеют строго параметров, остерегайтесь наследуемых методов, которые могут принимать параметры!):

foreach (MethodInfo mi in GetMethods(type))
{
   MethodInfo tempMi = mi; //modified closure
   object o = Activator.CreateInstance( type );
   Action myAction = delegate() { tempMi.Invoke(o, null); };
   ThreadStart ts = new ThreadStart(myAction);
   Thread thread1 = new Thread(ts);
   thread1.Start();
}

Если методы принимают параметры, выпришлось бы передать массив объекта (object [] { ... }) вместо null (в методе Invoke, вызываемом для текущего MethodInfo) соответственно;с конечно исправляет объекты в массиве.

На самом деле было бы лучше, если вы возьмете список потоков и добавите в него новый поток для каждого MethodInfo в списке, чтобы впоследствии вы могли контролировать их (например, если хотите остановить один).HashMap также будет хорошим выбором, ключом будет MethodInfo или Action, а значением будет связанный поток.

0 голосов
/ 06 января 2012

Вы можете создать экземпляр своего класса, используя Activator.

Затем вы можете вызвать один из его методов, используя Invoke.

Примерно так должно работать:

private void RunMethods(Type type)
{
    foreach( var item in lstMethodList.SelectedItems )
    {
        foreach( var method in type.GetMethods() )
        {
            if( String.Equals( item.ToString(), method.Name))
            {
                MethodInfo capturedMethod = method;
                var t = new Thread( () => ThreadMain( type, capturedMethod ) );
                t.Start();
            }
         }
     }
}

static void ThreadMain( Type type, MethodInfo mi )
{
    object o = Activator.CreateInstance( type );

    object[] parameters = new object[] { };

    mi.Invoke( o, parameters );
}

Я предположил, что у тестируемого класса есть конструктор без параметров.

0 голосов
/ 06 января 2012

Вы можете реализовать частный словарь, который содержит имя MethodInfos и Method.

private Dictionary<string, MethodInfo> methodList;
        private List<string> GetMethods(Type type)
        {
            methodList = new Dictionary<string, MethodInfo>();

            type.GetMethods().Where(m=>m.IsPublic && m.ReturnType.Equals(typeof(void))).ToList().ForEach(m=>
                methodList.Add(m.Name,m)
                );

            return methodList.Keys.Select(k => k).ToList();
        }

при выборе раскрывающегося списка вы можете найти метод в словаре и выполнить его.

...