关于 c#:Shut Down Dialog From A Thread

Shut Down Dialog From A Thread

我有一个在 c# windows 窗体下运行的应用程序。
当用户退出应用程序时,我想让用户关闭计算机。
我的应用程序有点复杂,但以下是我的问题的一个很好的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
public partial class Form1 : Form
{
    public class shell32
    {
        [DllImport("shell32", EntryPoint ="#60")]
        private static extern int SHShutDownDialog(long p);

        public static void ShutDownDialog()
        {
            int x = SHShutDownDialog(0);
        }
    }

    private Thread _eventHandler;
    private System.Windows.Forms.Button btnShutDown;

    public Form1()
    {
        InitializeComponent();

        AddSDButton();
        SetAndStartThread();
    }

    private void AddSDButton()
    {
        this.btnShutDown = new System.Windows.Forms.Button();
        this.SuspendLayout();
        this.btnShutDown.Location = new System.Drawing.Point(50, 50);
        this.btnShutDown.Name ="btnShutDown";
        this.btnShutDown.Size = new System.Drawing.Size(75, 25);
        this.btnShutDown.TabIndex = 0;
        this.btnShutDown.Text ="Shut Down";
        this.btnShutDown.UseVisualStyleBackColor = true;
        this.btnShutDown.Click += new System.EventHandler(this.btnShutDown_Click);

        this.Controls.Add(this.btnShutDown);
    }

    private void SetAndStartThread()
    {
        _eventHandler = new Thread(new ThreadStart(this.EventHandler));
        _eventHandler.IsBackground = true;
        _eventHandler.Start();
    }

    protected void EventHandler()
    {
        try
        {
            while (true)
            {
                //DO SOMETHING..
                Thread.Sleep(5000);
                shell32.ShutDownDialog();
            }
        }
        catch (ThreadAbortException)
        {
            return;
        }
    }

    private void btnShutDown_Click(object sender, EventArgs e)
    {
        shell32.ShutDownDialog();
    }

}

使用 btnShutDown_Click 通过表单调用关闭对话框可以正常工作。但是,正在运行的线程调用 shell32.ShutDownDialog 失败。 SHShutDownDialog 返回一个负值。
有什么想法吗?


您不能让后台线程访问 UI。 UI 必须始终在其自己的线程上运行。您的后台线程需要向您的主线程发布一条消息,以要求主线程打开对话框。

如何实现这种类型的跨线程异步消息传递,请看这个问题:

如何在 C# 中从工作线程发布 UI 消息