进行跨线程调用以隐藏表单visual c#

时间:2016-04-22 05:34:11

标签: c# multithreading winforms visual-studio timer

更新:解决方案已到达,现已接受。由于此问题上伪代码的清晰度,解决方案只需几秒钟。试图找出其他看似解决方案的解决方案"复制"问题花了很多时间。从我问这个问题的那一刻起,我就在20分钟内得到了解决方案。所以它不是重复的,可能是迄今为止最清楚的。

虽然已经就此提出了几个类似的问题,但我仍然无法将他们的工作代码整理在一起。我的主要应用程序不是在表单上,​​而是在一个单独的类中,它是一个插件并由宿主应用程序执行。

因此,虽然它似乎是一个重复的问题,但事实并非如此。请继续阅读。

我有我的主要课程。然后我有一个向用户显示信息的表单。当用户切换远离应用程序(主机应用程序失去焦点)时,我需要隐藏此表单。

我正在使用非常有限的API,因此我主持应用程序触发的处理事件的唯一方法。

我创建了一个每100毫秒触发一次的计时器,并检查用户是否将应用程序置于焦点。如果没有,则命令被发送到表单以隐藏自己。

这种方法的原因是因为主机应用程序失去焦点只是隐藏表单所需的众多场景之一,我需要通过相同的方法引导所有这些场景。

所有工作都来自其他类(从应用程序的其余部分调用Hide()方法没问题。 但是当计时器调用Hide()方法时,它不起作用,因为计时器在触发时位于不同的线程上。因此调用成为跨线程调用。

非常具体的问题是,我需要一个确切的示例代码,如何从定时器事件处理程序调用此形式的Hide()方法,并使用Invoke进行线程安全。

感谢。

这是计时器:

private void Controllel_Opened(object sender, EventArgs e)
{
    myTimer.Elapsed += new System.Timers.ElapsedEventHandler(DisplayTimeEvent);
    myTimer.Interval = 50;
    myTimer.Start();
}

public static System.Timers.Timer myTimer = new System.Timers.Timer();
// This method checks different scenarios when the tool tip should be hidden and calls the hiding method
public static void DisplayTimeEvent(object source, System.Timers.ElapsedEventArgs e)
{
    FormHandler.Hide();
}

然后" FormHandler"类:

public static class FormHandler
{
    private static Form1 frm1 = new Form1();

    public delegate void Form1HideEventHandler();
    public static event Form1HideEventHandler Form1Hide;

    public static void Hide()
    {
        if (Form1Hide != null)
        {
            Form1Hide();
        }

    }
}

然后是表格的代码:

public partial class Form1 : Form
{   
    public Form1()
    {
        InitializeComponent();
        FormHandler.Form1Hide += FormHandler_Form1Hide;
    }

    private void FormHandler_Form1Hide()
    {
        Hide();
    }
}

如果可能,我想获得具有确切代码的解决方案。感谢。

2 个答案:

答案 0 :(得分:2)

private void FormHandler_Form1Hide()
{
    if (InvokeRequired)
    {
        this.Invoke(new Action(() => { FormHandler_Form1Hide(); }));
    }
    else
    {
        Hide();
    }
}

答案 1 :(得分:1)

您需要使用System.Windows.Forms.Timer代替。这将调用回调度程序线程。