C# 启动一个STA线程,但使用最终函数的参数

C# 启动一个STA线程,但使用最终函数的参数,c#,delegates,nunit,C#,Delegates,Nunit,我对某些委托的行为有点不了解,例如传递一个方法作为要调用的参数。在尝试执行一些NUnit测试脚本时,我需要使用一些东西来运行许多测试。每个测试都需要创建一个GUI,因此需要一个STA线程。所以,我有点像 public class MyTest { // the Delegate "ThreadStart" is part of the System.Threading namespace and is defined as // public delegate void Threa

我对某些委托的行为有点不了解,例如传递一个方法作为要调用的参数。在尝试执行一些NUnit测试脚本时,我需要使用一些东西来运行许多测试。每个测试都需要创建一个GUI,因此需要一个STA线程。所以,我有点像

public class MyTest
{

   // the Delegate "ThreadStart" is part of the System.Threading namespace and is defined as
   // public delegate void ThreadStart();
   protected void Start_STA_Thread(ThreadStart whichMethod)
   {
      Thread thread = new Thread(whichMethod);
      thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
      thread.Start();
      thread.Join();
   }

   [Test]
   public void Test101()
   { 
      // Since the thread issues an INVOKE of a method, I'm having it call the
      // corresponding "FromSTAThread" method, such as
      Start_STA_Thread( Test101FromSTAThread );
   }

   protected void Test101FromSTAThread()
   {
      MySTA_RequiredClass oTmp = new MySTA_RequiredClass();
      Assert.IsTrue( oTmp.DoSomething() );
   }
}
这部分都很好。。。现在是下一步。我现在有一组不同的测试,也需要一个STA线程。然而,我需要做的每件“事情”都需要两个参数。。。两个字符串(对于本例)

如何声明正确的委托,以便传入需要调用的方法,以及一次调用两个字符串参数。。。在这种模式下,我可能有20多个测试要运行,并且可能有其他类似测试的未来,这些测试具有不同的参数计数和参数类型


谢谢。

您可以使用lambda表达式

以下是您希望在测试接受参数中调用的修改方法:

protected void Test101FromSTAThread(String arg1, Int32 arg2)
{
}
下面是如何使用lambda表达式调用
Start\u STA\u Thread

public void Test101()
{
   Start_STA_Thread(() => Test101FromSTAThread("foobar", 123));
}
本例中的lambda表达式为:

() => Test101FromSTAThread("foobar", 123)
这与所需的委托匹配。这两种方法都没有具有void返回类型的参数

如果您不熟悉lambda表达式,可以通过阅读MSDN了解更多信息。lambda表达式是一个匿名函数,在这里它创建一个委托。委托被传递给线程,当线程启动时,匿名函数被执行。在本例中,由于涉及线程,匿名函数将在您创建的线程上执行,而不是在测试运行线程上执行

当您在C#中使用lambda表达式时,编译器将发出一个具有代表匿名函数的“有趣”名称的函数。如果lambda表达式使用词法环境中的变量(例如,lambda表达式之前定义的局部变量),编译器将在特殊类型(同样使用“有趣”的名称)内生成匿名函数,以创建所谓的闭包。这允许编译器将词汇环境中的变量捕获到特殊类型的状态,并在稍后执行匿名函数时使用它。在您的例子中,这发生在线程启动时

上面的代码将生成类似这样的内容(“搞笑”名称
b_uu0
当然不会编译,但在IL中完全有效):

public void Test101()
{
开始线程(b_uu0);
}
//“匿名”功能。
无效b_u 0()
{
Test101FromSTAThread(“foobar”,123);
}

请注意如何将
b_uu0
用作
ThreadStart
委托。

如何使用Func或Action委托?希望这就是您所看到的。@zenwalker,好吧,但我不知道如何处理此类声明的正确语法,因此提出了这个问题。这意味着您希望使用Action或Func标准框架委托。操作用于void返回类型,Func用于返回类型方法调用。您可以执行操作myDel=MyClass.ToBeCalledMethod;myDel(someArgument);进一步阅读:虽然这是可行的,我会检查一下,你能简单地解释一下lambda表达式是如何工作的吗?我错过了一些东西。我认为这是在尝试先运行参数的方法。但是,它似乎将函数调用本身的签名以及相应的参数发送给函数。。。当函数准备就绪时,实际的“调用”最终运行哪个函数?
public void Test101()
{
   Start_STA_Thread(<Test101>b__0);
}

// The "anonymous" function.
void <Test101>b__0()
{
   Test101FromSTAThread("foobar", 123);
}