c#程序在事件发生后不会响应

时间:2014-05-26 15:48:02

标签: c# mono

我正在为程序开发一个用户界面,并且发生了一些非常奇怪的事情。

我有一个文本视图,2个按钮和一个进度条。我将控制台上的输出重定向到我的文本视图。所以,我点击我应该收到输出消息的按钮。在一开始它很好,但后来我使用了一些较长的例程,我正在尝试登录到Web服务并使用Web请求。

我的代码几乎可以正常工作,我可以登录并使我的网络请求正常。但是因为答案变慢了我创建了一些输出消息,并且我的问题开始了。我的界面不会更新,直到我在事件处理程序上创建的所有代码都运行完毕。当代码结束执行时,我一次收到所有输出消息。我甚至无法在程序运行时移动窗口..

我第一次在c#上编程,我不得不使用它,因为我需要使用dll ...而这种问题从未发生过。我通常使用Java。 这就像代码没有以正确的顺序运行而且对我来说没有意义..因为我知道我的代码是正确的,因为它在控制台上运行,并且在程序没有响应时运行.. < / p>

我似乎无法理解这一点,我是否应该使用线程处理事件?

class MainClass
{
    public static void Main (string[] args)
    {


        Application.Init ();
        UIMain win = new UIMain ();

        win.ShowAll ();
        Application.Run ();
    }
}



public partial class UIMain : Gtk.Window
{

    public UIMain () : 
        base (Gtk.WindowType.Toplevel)
    {
        System.Windows.Forms.Application.EnableVisualStyles ();
        this.Build ();


        Console.SetOut (new ControlWritter(this.textview1));


    }

    protected void OnButton2Clicked (object sender, EventArgs e)
    {
        if (entry1.Text.Equals(String.Empty) || entry2.Text.Equals(String.Empty)) {
            Console.WriteLine("random output");
        }

        ConstantesSetup.autoSetup ();

        button1.Sensitive = true;

        if (!ConstantesSetup.var1) {
            ConstantesSetup.routine6 ();
            ConstantesSetup.routine5 ();
            ConstantesSetup.routine4 ();
            ConstantesSetup.routine3 ();
            ConstantesSetup.routine2 ();

            ConstantesSetup.var1 = true;
        }
    }

    protected void OnButton1Clicked (object sender, EventArgs e)
    {
        switch (ConstantesSetup.erp) {
        case "ERP":
            eti_scp.autoSync (this);
            break;
        }
    }
}

我很抱歉缺少代码,但我甚至不知道是不是要开始寻找问题..

感谢您的时间;)

1 个答案:

答案 0 :(得分:0)

您正在使用长时间运行的同步操作阻止UI线程。您需要异步运行这些长时间运行的操作,以便当您的任务在后台运行时,按钮单击事件处理程序可以立即返回。

有多个选项可以异步运行任务,但一个简单的选项是使用BackgroundWorker。在您的事件处理程序中,您可以执行以下操作:

var worker = new BackgroundWorker();

worker.DoWork += (o, args) =>
{
    //call long running processes here
};

worker.RunWorkerAsync();

BackgroundWorker还会将这些操作分配给UI线程,以便您可以在DoWork回调方法中更新表单中的控件。