在另一个帖子中预加载表单

时间:2018-01-14 07:06:32

标签: c# multithreading forms winforms

我试图在一个单独的线程中在客户端表单的构造函数中预加载服务器表单。我的理由是服务器负载很耗时。

这是客户端表单,您可以在构造函数中看到我正在调用Preload()。还有一个按钮,单击它应该显示服务器,由于服务器表单已经预加载,因此该服务器应该很快:

public partial class Form1 : Form
{
    ServerUser server = null;
    public Form1()
    {
        InitializeComponent();
        Preload();
    }

    public async void Preload()
    {
      await  Task.Run(() =>
            {
                server = new ServerUser();
                server.LoadDocument();
                server.ShowDialog();
            }
        );
    }

    private void button1_Click(object sender, EventArgs e)
    {
        server.Show();
    }
}

在这里,我尝试在ServerUser的构造函数中预加载表单Form1,如果我点击button1服务器表单显示更快

以下是服务器表单:

public partial class ServerUser : Form
{
    public ServerUser()
    {
        InitializeComponent();
    }
    public void LoadDocument()
    {
        ConfigureSource();
    }

    public void ConfigureSource()
    {
        InvokeUpdateControls();
    }

    public void InvokeUpdateControls()
    {
          UpdateControls();
    }

    private void UpdateControls()
    {
        richTextBox1.Rtf = Resource1.ReferatPPC_Bun___Copy;
    }
}

2 个答案:

答案 0 :(得分:1)

您需要重新考虑您的设计。您应该从主UI线程创建所有表单,并将繁重的(非UI内容)卸载到后台线程。从后台线程调用UI方法会导致未定义的行为或异常。

另外,我认为你误解了await的作用。即使它是异步方法,也可以同步调用Preload()。这意味着,在调用server.Show();时,Server可能仍在运行以下方法之一:

server = new ServerUser(); //you should move this outside of Task.Run()
server.LoadDocument(); //implement this method using background threads
server.ShowDialog(); //this will actually throw an exception if called via Task.Run();

从您的示例中我认为LoadDocument是一项昂贵的操作。您应该重写该方法以在后台线程上运行,并使ServerUser显示加载屏幕,直到LoadDocument()完成。确保通过BeginInvoke调用LoadDocument中的所有UI方法 或正确 async / await。

答案 1 :(得分:0)

发送构造函数;

public partial class ServerUser : Form
{
public ServerUser(Form1 form1)
{
    InitializeComponent();
    form1.Preload();
}
public void LoadDocument()
{
    ConfigureSource();
}

public void ConfigureSource()
{
    InvokeUpdateControls();
}

public void InvokeUpdateControls()
{
      UpdateControls();
}

private void UpdateControls()
{
    richTextBox1.Rtf = Resource1.ReferatPPC_Bun___Copy;
}
}



public partial class Form1 : Form
{
ServerUser server = null;
public Form1()
{
    InitializeComponent();
    Preload();
}

public async void Preload()
{
  await  Task.Run(() =>
        {
            server = new ServerUser();
            server.LoadDocument();
            server.ShowDialog();
        }
    );
}

private void button1_Click(object sender, EventArgs e)
{
    server=new ServerUser(this);// or whatever you want
    server.Show();
}
}