使用分配的线程调用不同函数的多态方式

时间:2015-04-09 04:15:52

标签: c# multithreading plugins scheduled-tasks mef

我有一个class,其中包含一组参数和参数类型不同的函数。我一直试图找到一种方法来调用在已分配线程内调用所需函数。

这是一个简单的方法吗?我已查看System.Action,但这需要知道参数。我已经过了TaskFactoryTPL,但从我见过的例子中,我无法将解决方案整理在我脑海中。

我最终要做的是排队将由有限数量的线程执行的作业。执行的工作是简单的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)

我不仅仅喜欢使用字符串列表来填充我的所有参数,但我并不知道另一种方法。也许我后来投射的对象列表?这两个想法都非常混乱......

1 个答案:

答案 0 :(得分: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方法,则代码可能几乎没有变化。