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

Polymorphic way to call different functions with an allocated thread

我有一个 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)

我不希望只使用字符串列表来放入我的所有参数,但我真的不知道还有其他方法可以做到这一点。也许是我稍后投射的对象列表?这两个想法都很乱...

我假设 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 本身中,则代码可能会有很小的变化。