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