2015-04-09 1 views
0

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

Что такое простой способ сделать это? Я просмотрел System.Action, но это требует, чтобы параметры были известны. Я также перешел TaskFactory и TPL, но из примеров, которые я видел, я не могу собрать решение в своей голове.

В конечном итоге я хочу, чтобы задания очереди выполнялись ограниченным числом потоков. Выполненные задания просты: HTTP запросов.

Я чувствую, что это было сделано раньше и имеет простое решение, но оно ускользало от меня в течение нескольких недель. Я надеюсь на элегантный способ сделать это, а не много сложного кода.

Я также пытаюсь реализовать плагины MEF, чтобы усугубить ситуацию.

public bool AddThreads(int numOfThreads) 
    { 
     try 
     { 
      // Exit if no plugin type is set 
      if (PluginType == "") return false; 

      int totalThreads = numOfThreads + threads.Count; 
      for (int i = threads.Count; i < totalThreads; i++) 
      { 
       // Create an instance of the MEF plugin 
       var task = PluginHandler.CreateInstance(PluginType); 
       threads.Add(task); 

       task.ThreadId = i; 

       task.OnStatusChange += new TaskerPlugin.EventHandler(ChangeStatus); 
       task.OnActionComplete += new TaskerPlugin.EventHandler(ReportComplete); 
       task.OnActionSuccess += new TaskerPlugin.EventHandler(ReportSuccess); 
       task.OnActionFailure += new TaskerPlugin.EventHandler(ReportFailure); 
       task.OnActionAttempt += new TaskerPlugin.EventHandler(ReportAttempt); 
       task.OnActionError += new TaskerPlugin.EventHandler(ReportError); 
       task.OnActionCancelled += new TaskerPlugin.EventHandler(ReportCancellation); 
       task.OnActionBegin += new TaskerPlugin.EventHandler(ReportStartOfTask); 
       task.OnActionEnd += new TaskerPlugin.EventHandler(ReportEndOfTask); 

       // Do work from plugin 
       // This is where I'd like to call different 
       // functions possibly inside Start() 
       task.Start(); 
      } 

      return true; 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 

Текущий код вызова функции:

private void CreateThreads(int threadCount) 
    { 
     // taskMan is a class variable to queue more jobs in the future 
     taskMan = new TaskManager(PLUGIN_FOLDER) 
     { 
      PluginType = PLUGIN_TYPE, 
      UseProxies = (_config.IpSolution == "Proxies" || _config.IpSolution == "Proxy URL") 
     }; 

     taskMan.AddThreads(threadCount); 
    } 

Я хочу, чтобы в конечном итоге просто вызвать функцию, чтобы добавить работу к нему с определенным числом нитей:

private void AddJob(string pluginName, string methodName, List<string> args) 

Я d предпочитаю не просто использовать строковый список для ввода всех моих аргументов, но я действительно не знаю другого способа сделать это. Может быть, список объектов, которые я потом брошу позже? Обе эти идеи очень беспорядочны ...

+2

Вы можете поделиться некоторыми кодами? – bit

+0

Да, я могу! Тем не менее, это немного уродливо со всеми событиями. – Phil

+0

Вы пробовали использовать BackgroundWorker? Это позволяет вам передать объектный параметр самому себе, возможно, это может вам помочь. Взгляните сюда: http://stackoverflow.com/a/4807200/1508398 – bit

ответ

0

Я предполагаю, что AddJob - это перегруженный метод, который вам нужно вызвать с различными параметрами.

Вы, возможно, придется настроить ваш PluginHandler.CreateInstance(PluginType) способ сделать что-то вроде этого при создании задачи, это позволит вам выполнить любой метод, который нужно в задаче, которую вы создаете ..

Task task = new Task(() => 
{ 
    classInstance.YourMethod("some param1", some other param2)); 
} 

Далее с некоторыми отражение ..

var classInstance = new YourClass(); 
Type type = classInstance.GetType(); 
MethodInfo methodInfo = type.GetMethod("AddJob"); 
object[] parametersArray = new object[] { "some param1", "some parma2" }; 
methodInfo.Invoke(methodInfo, parametersArray); 

и, наконец,

Task task = new Task(() => 
{ 
    var classInstance = new YourClass(); 
    Type type = classInstance.GetType(); 
    MethodInfo methodInfo = type.GetMethod("AddJob"); 
    object[] parametersArray = new object[] { "some param1", "some parma2" }; 
    methodInfo.Invoke(classInstance, parametersArray); 
} 

В случае, если метод AddJob присутствует в текущем class, код может немного измениться.

Смежные вопросы