Reputation: 29
I am trying to preload server form in the constructor of client form, in a separate thread. My reason is that server load is time consuming.
Here's the client form, you can see in the constructor that I am calling Preload()
. There's also a button, clicking on it should show the server, which should be fast since the server form is already preloaded:
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();
}
}
Here I try to preload form ServerUser
in constructor of Form1
and if I click on button1 Server form show faster
And here's the server form:
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;
}
}
Upvotes: 1
Views: 1266
Reputation: 1224
You need to rethink your design. You should create all forms from the main UI thread, and offload the heavy lifting(non UI stuff) to the background threads. Calling UI methods from background threads results in undefined behavior or exceptions.
Also, I think you misunderstand what await
does. You call Preload()
synchronously even though it is an asynchronous method. This means that by the time server.Show();
is called, Server might still be running one of these methods:
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();
From your sample I suppose LoadDocument is the expensive operation. You should rewrite that method to run on a background thread and make ServerUser
show a loading screen untill LoadDocument()
completes. Make sure that all UI methods from LoadDocument are called via BeginInvoke
or proper async/await.
Upvotes: 1
Reputation: 885
Send in constructor;
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();
}
}
Upvotes: 0