【问题标题】:C# Passing method name to parameterizedthreadstart with variableC#将方法名称传递给带有变量的参数化threadstart
【发布时间】:2012-11-06 19:22:57
【问题描述】:

好吧,伙计们,请不要因为我问这个问题而对我大发雷霆。

// 使用 System.Threading;

    private void startThread()
    {            
        Thread t = new Thread(ParameterizedThreadStart(setOutputBinaryWorker));
        t.Start();
    }

由于 setOutputBinaryWorker 是一个实际存在的方法,所以这可以正常工作。但是,我正在寻找一种将函数名称作为变量传递给 startThread 函数的方法。

由于我有限的 C# 经验,我怀疑这是可能的,但似乎无法弄清楚如何。我可以想象它应该是这样的:

// using System.Threading;

    private void startThread(??datatype?? func)
    {            
        Thread t = new Thread(ParameterizedThreadStart(func));
        t.Start();
    }

但我无法弄清楚数据类型应该是什么(使用问号)。 现在,在调试时,传递的函数名称弹出为

System.Object 无效,setOutputBinaryWorker

这并没有给我太多的继续。这些可以创建吗?尝试将参数转换为(对象),但不起作用。

这背后的主要思想是尝试使用安全的 gui 线程以正确的方式写入 ui 元素。 现在,我已经完成了那部分,使用委托方法,这一切都很好。但是当切换到当前方法(使方法名称可变)时,我完全迷失了。 如果有人知道替代、更好或至少可行的解决方案,我愿意接受建议,很重要。

提前感谢您的努力。

【问题讨论】:

  • 你为什么不直接传入一个ParameterizedThreadStart?另外:对于 ParameterizedThreadStart 版本,您不需要将值传递给 Start 吗?
  • 感谢您的快速回复,是的,我愿意。回答您的问题:这行不通,我需要传递函数名称,因为它将被包装在外部 dll 中。
  • 你打算以这种方式调用什么样的方法?它们会有相同的签名和返回值吗?
  • 这个想法是创建一个带有一些通用函数的dll文件。其中之一是创建 gui 线程的能力。这些方法的类型总是无效的。

标签: c# multithreading visual-studio-2010 pass-by-reference


【解决方案1】:

我会使用 lambda 表达式

Thread t =new Thread(
 () =>
  {
    function(anyparameter);
  }
 ).Start();

【讨论】:

  • 好的,我很感兴趣,但这究竟是做什么的?它以哪种方式替换我的代码?
  • @Digitalis 不使用ParameterizedThreadStart,你可以只传递参数
  • 好的。对不起,我相信这比我的工资等级高一点。你是说我最初要求的选项是不可能的?或者这只是更快/更好/更新?
  • @Digitalis 你要求替代品,这是一个
  • 没错,只有我想了解我在编码的内容 :) 不要误会我的意思,感谢您的回答和时间,但它是如何工作的?跨度>
【解决方案2】:

数据类型应该是带签名的委托:

void (object) - 意思是一个不返回任何东西并接受对象参数的方法

例子:

delegate void TestDelegate(object o);

        private void button4_Click(object sender, EventArgs e)
        {
            TestDelegate custom = SomeMethod;
            ParameterizedThreadStart pts = new ParameterizedThreadStart(custom);
            Thread thread = new Thread(pts);
            thread.Start();
        }

        private void SomeMethod(object o)
        {
            MessageBox.Show("Hey!");
        }

请注意,我们传入了一个 TestDelegate 类型的变量。这使您可以在运行时将不同的方法传递给线程,只要方法遵循委托签名即可。

与反射配对:

    // assuming class is in same assembly as this method
    Assembly assembly = Assembly.GetExecutingAssembly();
    // you can choose to get type from an known object instead
    Type type = assembly.GetType("Test.SomeClass");
    object instance = Activator.CreateInstance(type, null);            
    MethodInfo methodInfo = type.GetMethod("SomeMethod");                        
    object[] parameterValues = new object[] { 1 };            
    methodInfo.Invoke(instance, parameterValues);

使用反射时请注意性能。如果可以的话,缓存创建的对象以取消使用反射创建对象。

【讨论】:

  • 感谢您的回复。我理解的委托数据类型。但是,如果我错了,请纠正我,但 SomeMethod 仍然必须是现有函数。练习的重点是消除这一点。我想设置该函数,以便可以将另一个类中定义的委托方法传递给它以与 parameterizedThreadStart 一起使用。
  • 相比之下。 PHP 允许函数名作为字符串传递。因此,如何以及在何处定义函数完全取决于您。在 C# 中是否有类似的可能,还是根本不想这样做?
  • 反射是否符合您的要求?我更新了我的答案以包括反射。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多