C# 通过计时器C删除ListView中的项#

C# 通过计时器C删除ListView中的项#,c#,listview,timer,C#,Listview,Timer,我有一个带有一些入口的C#ListView,一个删除第一个入口的方法和一个调用此方法的计时器。我的问题是,计时器工作得很好(我通过调用MessageBox对此进行了检查),remove方法也很好(我通过使用按钮调用此方法而不是通过计时器进行检查)。但是计时器仍然不能从我的ListView中删除项目 我的代码: void Button1Click(object sender, EventArgs e) { removeItems(); } priv

我有一个带有一些入口的C#ListView,一个删除第一个入口的方法和一个调用此方法的计时器。我的问题是,计时器工作得很好(我通过调用MessageBox对此进行了检查),remove方法也很好(我通过使用按钮调用此方法而不是通过计时器进行检查)。但是计时器仍然不能从我的ListView中删除项目

我的代码:

    void Button1Click(object sender, EventArgs e)
    {
        removeItems();
    }

    private void timer_Tick(object sender, System.Timers.ElapsedEventArgs e)
    {
        removeItems();      
    }

    void removeItems()
    {
        MessageBox.Show("Hello from the removeMethod");
        listViewTeam.Items.RemoveAt(0);
    }
removeItems()的两个调用;让messageBox出现,但只让按钮也删除listView的第一项


有人可以帮助我如何通过计时器删除第一项吗?

您使用的计时器不是线程安全的。您应该使用
System.Windows.Forms.Timer
,而不是使用
System.Timer
,因为它会自动在UI线程上运行。然后,您的代码就可以正常工作。

您似乎正在使用
系统。计时器
,这意味着您的
已用时间
回调不一定会在UI线程上调用。您可以通过使用
Invoke
来确保它能够执行

if (listViewTeam.InvokeRequired)
{
    listViewTeam.Invoke((MethodDelegate)delegate { listViewTeam.Items.RemoveAt(0); });
}

或者更容易地将计时器的属性设置为包含
列表视图的表单,这样代码就可以正常工作。

首先启动计时器。但是使用

您的设计器类:

partial class Form1
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container();
        this.listBox1 = new System.Windows.Forms.ListBox();
        this.timer1 = new System.Windows.Forms.Timer(this.components);
        this.SuspendLayout();
        // 
        // listBox1
        // 
        this.listBox1.FormattingEnabled = true;
        this.listBox1.Items.AddRange(new object[] {
        "q",
        "w",
        "e",
        "r",
        "t",
        "y",
        "u",
        "sfdgsdf",
        "gf",
        "gsd",
        "fgs",
        "dfg"});
        this.listBox1.Location = new System.Drawing.Point(170, 200);
        this.listBox1.Name = "listBox1";
        this.listBox1.Size = new System.Drawing.Size(120, 95);
        this.listBox1.TabIndex = 0;
        // 
        // timer1
        // 
        this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(570, 502);
        this.Controls.Add(this.listBox1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.Load += new System.EventHandler(this.Form1_Load);
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.ListBox listBox1;
    private System.Windows.Forms.Timer timer1;
}

您需要使用
委托
从后台线程安全地与UI控件交互(这是您在实现
计时器
时真正要做的事情):


就像SLC说的,你需要使用BeginInvoke。就我个人而言,我已经这样解决了

  public AddListItem myDelegate;
您应该检查:


您使用的是哪种定时器?System.Timer还是System.Windows.Forms.Timer?你在计时器上调用Start()方法了吗?编辑:刚刚看到您使用了系统计时器。正如其他人所说,使用Winforms计时器并调用Start()“您使用的计时器不是线程安全的”-错误,您建议的不是。System.Windows.Forms.Timer此Timer类引发的计时器事件与Windows Forms应用程序中的其余代码同步。驻留在计时器事件处理程序中的任何代码(对于这种类型的计时器类)都使用应用程序的UI线程执行。对于windows窗体应用程序来说,它是完全线程安全的。在windows窗体应用程序中,当使用单个UI线程时,它是线程安全的,是的
Forms.Timer
是专为单线程环境设计的,因此它不是线程安全的。例如,您不能在多线程环境中使用它。本身甚至声明“Windows窗体计时器组件是单线程的,精度限制为55毫秒。如果您需要精度更高的多线程计时器,请使用System.Timers命名空间中的Timer类。”。访问此链接,在UI线程上运行窗体计时器时,使用窗体计时器要简单得多,但这是另一种调用交叉线程的解决方案。它更简单,但不太准确——这一切实际上取决于计时器的用途以及它在什么上下文中使用。
void Button1Click(object sender, EventArgs e)
{
    removeItems();
}

private void timer_Tick(object sender, System.Timers.ElapsedEventArgs e)
{
    removeItems();      
}

void removeItems()
{
    MessageBox.Show("Hello from the removeMethod");
    RemoveListViewItem(0);
}

public delegate void InvokeRemoveListViewItem(Int32 ItemIndex);
public void RemoveListViewItem(Int32 ItemIndex)
{
    if (InvokeRequired)
    {
        try { Invoke(new InvokeRemoveListViewItem(RemoveListViewItem), new Object[] { ItemIndex }); }
        catch (Exception)
        {
            //react to the exception you've caught
        }
    }

    listView.RemoveAt(ItemIndex);
}
  public AddListItem myDelegate;
                               Windows.Forms       System.Timers         System.Threading 
Timer event runs on what thread?    UI thread      UI or worker thread   Worker thread 
Instances are thread safe?          No             Yes                   No 
Familiar/intuitive object model?    Yes            Yes                   No 
Requires Windows Forms?             Yes            No                    No 
Metronome-quality beat?             No             Yes*                  Yes* 
Timer event supports state object?  No             No                    Yes 
Initial timer event schedulable?    No             No                    Yes 
Class supports inheritance?         Yes            Yes                   No

* Depending on the availability of system resources (for example, worker threads)