C# 使用winforms,如何在Action1堆栈之外执行由Action1发起的Action2?
我有C# 使用winforms,如何在Action1堆栈之外执行由Action1发起的Action2?,c#,.net,winforms,C#,.net,Winforms,我有Action2,它在自动调用(例如从菜单项)时工作得很好,但是当从Action1调用时,该操作会显示奇怪的错误 private void button1_Click(object sender, EventArgs e) { Action action2 = () => Console.WriteLine("Action 2"); Action action1 = () => {
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();
}
如何从Action1
启动Action2
,使Action1
不在Action2
的堆栈中
我当前的解决方案是使用定时器
控件
有更优雅的解决方案吗
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。一种有保证的方法是创建一个线程实例,并使用ThreadStartDelegate调用该操作。然而,如果这不是关键,并且你更感兴趣的是并行地做这些,我建议使用TPL。 因此,您只需执行以下操作: 任务action2Task=Task.Factory.StartNew(操作2) 希望这有帮助
澄清后的补充答复: 因此,您似乎应该通过调度程序从
Action1
弹出Action2
:
Dispatcher.BeginInvoke(操作2)代码>我很确定Action1
在某种程度上总是在Action2
的堆栈中,这就是堆栈的工作方式,还是我在这里遗漏了什么?没有足够的代码来查看这里发生了什么。您还没有给出任何指示,说明什么是Action1
和Action2
。@miroxlav例如,当您应该格式化为code
@Servy-Action1
时,将您的变量加粗<代码>操作2正在注销,关闭所有MDI表单并显示登录表单。但每当我从这样的事件(Action1
on stack)中执行注销时,除了第一次之外,登录表单中的表单事件都会消失。一旦登录表单关闭,它们都会得到处理(第一次除外)。在我看来,代码非常简单,它看起来像WinForms的一些bug(或奇怪的特性)。听起来你只是想在一个非UI线程中完成UI工作。不要那样做;你需要封送到UI线程来做UI工作。我在考虑这个问题,但是Action2
也做UI工作。我不应该在两个线程上使用UI。然后使用dispatcher:dispatcher.BeginInvoke(action2)你能把你最后的评论作为答案的一部分吗?它涵盖了我的情况。然后答案将变为“可接受”:)当前答案可以放在----
行下面,因为它稍微偏离主题。