"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,使 timercount non-static 专用于表单的每个实例。