使用 winforms,如何在 Action1 堆栈之外执行由 Action1 发起的 Action2?
With winforms, how to execute Action2 originated by Action1 outside of stack of Action1?
我有 Action2
它在自动调用时运行良好,例如来自菜单项,但此操作在从 Action1
.
调用时显示奇怪的错误
如何以 Action1
不会在 Action2
堆栈中的方式从 Action1
启动 Action2
?
我目前的解决方案是使用 Timer
控件。
有没有更优雅的方案?
Timer handoverToAction2 = new Timer();
void Action1()
{
DoWhateverNeeded();
handoverToAction2.Start();
}
void handoverToAction2_Tick(Object sender, EventArgs e)
{
handoverToAction2.Stop();
Action2();
}
您可以尝试调用主线程以在其中设置 Action2
运行。这是一个来自 WinForm 的示例,其中 Action1
调用到主线程以调用 Action2
。当我在这里检查调试器中的堆栈跟踪时,看起来 Action2
不在 Action1
.
的调用堆栈中
private void button1_Click(object sender, EventArgs e)
{
Action action2 = () => Console.WriteLine("Action 2");
Action action1 = () =>
{
Console.WriteLine("Action1");
BeginInvoke((MethodInvoker)delegate
{
action2();
});
};
action1();
}
您需要在不同的线程上启动 action2。一种有保证的方法是创建一个 Thread 实例,并使用 ThreadStartDelegate 调用该操作。但是,如果这不是关键,并且您对并行执行这些操作更感兴趣,我建议您使用 TPL。
所以你只需要这样做:
任务 action2Task = Task.Factory.StartNew(action2);
希望对您有所帮助!
澄清后追加回答:
所以您似乎应该 spring 来自 Action1
的 Action2
通过 Dispatcher:
Dispatcher.BeginInvoke(action2);
我有 Action2
它在自动调用时运行良好,例如来自菜单项,但此操作在从 Action1
.
如何以 Action1
不会在 Action2
堆栈中的方式从 Action1
启动 Action2
?
我目前的解决方案是使用 Timer
控件。
有没有更优雅的方案?
Timer handoverToAction2 = new Timer();
void Action1()
{
DoWhateverNeeded();
handoverToAction2.Start();
}
void handoverToAction2_Tick(Object sender, EventArgs e)
{
handoverToAction2.Stop();
Action2();
}
您可以尝试调用主线程以在其中设置 Action2
运行。这是一个来自 WinForm 的示例,其中 Action1
调用到主线程以调用 Action2
。当我在这里检查调试器中的堆栈跟踪时,看起来 Action2
不在 Action1
.
private void button1_Click(object sender, EventArgs e)
{
Action action2 = () => Console.WriteLine("Action 2");
Action action1 = () =>
{
Console.WriteLine("Action1");
BeginInvoke((MethodInvoker)delegate
{
action2();
});
};
action1();
}
您需要在不同的线程上启动 action2。一种有保证的方法是创建一个 Thread 实例,并使用 ThreadStartDelegate 调用该操作。但是,如果这不是关键,并且您对并行执行这些操作更感兴趣,我建议您使用 TPL。 所以你只需要这样做: 任务 action2Task = Task.Factory.StartNew(action2);
希望对您有所帮助!
澄清后追加回答:
所以您似乎应该 spring 来自 Action1
的 Action2
通过 Dispatcher:
Dispatcher.BeginInvoke(action2);