"Invoke or BeginInvoke cannot be called on a control until" 在标签上
"Invoke or BeginInvoke cannot be called on a control until" on a Label
我已经阅读了几个与此问题相关的 questions/answers 但找不到适用于该问题的解决方案。
我有一个表单 (MainForm
) 和一个按钮 (Upload
)。当我单击按钮时(从 ComboBox 选择要上传到服务器的文件后),它会打开另一个表单 (UploadBackupForm
) 并将文件上传到服务器。上传过程在UploadBackupForm
中控制,表格如下:
只要上传一次就可以工作,我的意思是,UploadBackupForm
被调用一次。我第二次单击“上传”按钮时,UploadBackupForm
打开并且(在上传一些数据后)它抛出一条错误消息:
System.InvalidOperationException: 'Invoke or BeginInvoke cannot be called on a control until the window handle has been created.'
在此特定行:
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
因为 timer
变量是静态的,即使在关闭表单后它仍然存在。它包含对委托的引用,该委托持有对表单的引用,因此以前的实例在应用程序的整个生命周期中都保持活动状态。此外,单个 timer
发布对所有先前实例以及当前实例的回调。
正如正确指出的那样 by Evk,使 timer
和 count
non-static 专用于表单的每个实例。
我已经阅读了几个与此问题相关的 questions/answers 但找不到适用于该问题的解决方案。
我有一个表单 (MainForm
) 和一个按钮 (Upload
)。当我单击按钮时(从 ComboBox 选择要上传到服务器的文件后),它会打开另一个表单 (UploadBackupForm
) 并将文件上传到服务器。上传过程在UploadBackupForm
中控制,表格如下:
只要上传一次就可以工作,我的意思是,UploadBackupForm
被调用一次。我第二次单击“上传”按钮时,UploadBackupForm
打开并且(在上传一些数据后)它抛出一条错误消息:
System.InvalidOperationException: 'Invoke or BeginInvoke cannot be called on a control until the window handle has been created.'
在此特定行:
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
因为 timer
变量是静态的,即使在关闭表单后它仍然存在。它包含对委托的引用,该委托持有对表单的引用,因此以前的实例在应用程序的整个生命周期中都保持活动状态。此外,单个 timer
发布对所有先前实例以及当前实例的回调。
正如正确指出的那样 timer
和 count
non-static 专用于表单的每个实例。