我已经阅读了与此问题相关的几个问题/答案,但找不到适用于问题的解决方案。
我有一个表单(MainForm
)和一个按钮(Upload
)。当我单击按钮(从ComboBox中选择要上传到服务器的文件后),它会打开另一个表单(UploadBackupForm
)并将文件上传到服务器。上传过程由UploadBackupForm
控制,表单如下所示:
只要上传完成一次就行了,我的意思是UploadBackupForm
被调用一次。我第二次点击上传按钮,UploadBackupForm
打开,并且(在上传一些数据后)它会抛出错误说:
System.InvalidOperationException:在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。'
在此特定行:
DurationLabel.Invoke((MethodInvoker)delegate
{
DurationLabel.Text = Count2Duration(count);
});
这让我感到困惑,因为它在完成一次后起作用,而在第二次起作用时不起作用。我在C#中有基本的知识,所以我不知道是什么导致了这个以及如何解决它。
MainForm
:
private void Upload2ServerButton_OnClick(object sender, EventArgs e)
{
Form UBF = new UploadBackupForm();
UBF.ShowDialog();
}
UploadBackupForm
:
public partial class UploadBackupForm : Form
{
public UploadBackupForm()
{
InitializeComponent();
}
public static System.Timers.Timer timer = new System.Timers.Timer();
public static int count = 0;
private void UploadBackup_Load(object sender, EventArgs e)
{
timer.Interval = 1000;
timer.Elapsed += new ElapsedEventHandler(delegate {
count++;
// didn't do any good (this.IsHandleCreated or DurationLabel.IsHandleCreated)
// if (!this.IsHandleCreated)
// {
// this.CreateControl();
// }
DurationLabel.Invoke((MethodInvoker)delegate
{
DurationLabel.Text = Count2Duration(count);
});
});
// upload the archive to the server
new Thread((ThreadStart)delegate
{
FTP.Item[] items = FTP.ListDirectoryDetails(DataIO.FTP.Server, DataIO.FTP.Username, DataIO.FTP.Password, DataIO.FTP.UploadDir);
// here, I upload the file to the server and update the progress bar and the uploaded / total labels
答案 0 :(得分:3)
因为timer
变量是静态的,所以即使在表单关闭后它仍然存在。它包含对委托的引用,该委托保存对表单的引用,以便先前的实例在应用程序的生命周期内保持活动状态。此外,单个timer
发布回调所有先前实例以及当前实例。
正如in the comments正确指出Evk一样,timer
和count
是非静态的,因此它们专用于表单的每个实例。