与winform相比,来自控制台的过程

时间:2012-04-26 12:48:50

标签: c# winforms delegates

以下控制台应用程序运行正常 - 我很惊讶它没有错误。

class DelegateExperiments
{

    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //open notepad when the console begins
    //create an event that fires and writes "Notepad closed" in the console
    //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    //instance variables of the form
    private const string helloText = "hello world";
    private const string exitText = "you just closed notepad";
    private Process myProcess;
    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<        


    static void Main(string[] args)
    {

        Console.WriteLine(helloText);

        DelegateExperiments myInstance;
        myInstance = new DelegateExperiments();
        myInstance.Foo();

        Console.Read();
    }

    void Foo()
    {

        myProcess = new Process();
        myProcess.StartInfo.FileName = @"notepad.exe";
        myProcess.Exited += MyProcessExited;
        myProcess.EnableRaisingEvents = true;
        //myProcess.SynchronizingObject = this;
        myProcess.Start();

    }

    private void MyProcessExited(Object source, EventArgs e)
    {
        Console.WriteLine(exitText);
    }


}

如果我尝试使用winform做类似的事情,即将信息写回表单上的标签,那么它就会更复杂,需要行myProcess.SynchronizingObject = this;才能工作。为什么他们会有所不同?

2 个答案:

答案 0 :(得分:6)

有意将Console类编写为线程安全的。你可以从任何线程调用它。它甚至可以确保不会“重叠”来自不同线程的调用。 Console.Write/WriteLine是原子的。这是因为Console旨在与shell交互,而shell的一个主要目的是能够从多个进程收集输入。能够做到这一点是一项相当大的工作,但需要做到这一点才能真正实现其目的。

GUI对象(例如标签)的设计没有考虑到这一点。

答案 1 :(得分:0)

在WinForms中,对UI元素的所有访问都必须位于专用UI线程上。请参阅第1.2.1节here

正如文件所说:

  

当可视Windows窗体组件处理Exited事件时,   例如Button,通过系统线程访问组件   池可能不起作用,或者可能导致异常。避免这样做   将SynchronizingObject设置为Windows窗体组件,这会导致   处理在同一线程上调用的Exited事件的方法   在哪个组件上创建。