C# 启动一个STA线程,但使用最终函数的参数
我对某些委托的行为有点不了解,例如传递一个方法作为要调用的参数。在尝试执行一些NUnit测试脚本时,我需要使用一些东西来运行许多测试。每个测试都需要创建一个GUI,因此需要一个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
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);
}