我的代码遇到了另一个问题。
情景:
我使用后台工作程序使用XML文件中的数据填充listView。一切正常,但是当我使用后台工作程序填充listView时,它会一遍又一遍地重复,通常是3-5次。这是我的完整代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
namespace THC_Poker_Notifier
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
int FPPFee = 0;
string StartDate;
// Control Invike functions for multi-threading
delegate void UniversalVoidDelegate();
public static void ControlInvike(Control control, Action function)
{
if (control.IsDisposed || control.Disposing)
return;
if (control.InvokeRequired)
{
control.Invoke(new UniversalVoidDelegate(() => ControlInvike(control, function)));
return;
}
function();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void supportThisProjectToolStripMenuItem_Click(object sender, EventArgs e)
{
SupportProject donate = new SupportProject();
donate.ShowDialog();
}
private void Main_Load(object sender, EventArgs e)
{
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
}
}
private void LoadAllTournaments()
{
ControlInvike(listView1, () => listView1.Items.Clear());
DataSet ds = new DataSet();
ds.ReadXml("https://www.pokerstars.com/datafeed/tournaments/all.xml");
ListViewItem item;
foreach (DataRow dr in ds.Tables["tournament"].Rows)
{
DateTimeOffset startDate = DateTimeOffset.ParseExact((string)dr["start_date"], "yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
TimeZone localZone = TimeZone.CurrentTimeZone;
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(localZone.StandardName.ToString());
DateTimeOffset converted = TimeZoneInfo.ConvertTime(startDate, tz);
if (dr["play_money"].ToString() != "true")
{
FPPFee = Convert.ToInt32(dr["fpp_fee"]);
if (FPPFee == 0)
{
if (dr["buy_in_fee"].ToString() != "$0 + $0")
{
item = new ListViewItem(new string[] { dr["name"].ToString(), converted.ToString("d"), converted.ToString("t"), dr["buy_in_fee"].ToString(), dr["prize"].ToString(), dr["players"].ToString(), dr["status"].ToString(), dr["id"].ToString() });
ControlInvike(listView1, () => listView1.Items.Add(item));
Thread.Sleep(10);
}
}
}
}
}
private void LoadRegularTournaments()
{
ControlInvike(listView2, () => listView2.Items.Clear());
DataSet ds = new DataSet();
ds.ReadXml("http://46.101.5.145/Feeds/regular.xml");
ListViewItem item2;
foreach (DataRow dr in ds.Tables["tournament"].Rows)
{
StartDate = dr["start_date"].ToString();
FPPFee = Convert.ToInt32(dr["fpp_fee"]);
if (FPPFee == 0)
{
if (dr["buy_in_fee"].ToString() != "$0 + $0")
{
item2 = new ListViewItem(new string[] { dr["name"].ToString(), StartDate.Substring(0, 10), StartDate.Substring(12, 7), dr["buy_in_fee"].ToString(), dr["prize"].ToString(), dr["players"].ToString(), dr["status"].ToString(), dr["id"].ToString() });
ControlInvike(listView2, () => listView2.Items.Add(item2));
}
}
}
}
private void LoadSatelliteTournaments()
{
ControlInvike(listView3, () => listView3.Items.Clear());
DataSet ds = new DataSet();
ds.ReadXml("http://46.101.5.145/Feeds/satellite.xml");
ListViewItem item3;
foreach (DataRow dr in ds.Tables["tournament"].Rows)
{
StartDate = dr["start_date"].ToString();
FPPFee = Convert.ToInt32(dr["fpp_fee"]);
if (FPPFee == 0)
{
if (dr["buy_in_fee"].ToString() != "$0 + $0")
{
item3 = new ListViewItem(new string[] { dr["name"].ToString(), StartDate.Substring(0, 10), StartDate.Substring(12, 7), dr["buy_in_fee"].ToString(), dr["prize"].ToString(), dr["players"].ToString(), dr["status"].ToString(), dr["id"].ToString() });
ControlInvike(listView3, () => listView3.Items.Add(item3));
}
}
}
}
private void LoadSpecialTournaments()
{
ControlInvike(listView4, () => listView4.Items.Clear());
DataSet ds = new DataSet();
ds.ReadXml("http://46.101.5.145/Feeds/special.xml");
ListViewItem item4;
foreach (DataRow dr in ds.Tables["tournament"].Rows)
{
StartDate = dr["start_date"].ToString();
FPPFee = Convert.ToInt32(dr["fpp_fee"]);
if (FPPFee == 0)
{
if (dr["buy_in_fee"].ToString() != "$0 + $0")
{
item4 = new ListViewItem(new string[] { dr["name"].ToString(), StartDate.Substring(0, 10), StartDate.Substring(12, 7), dr["buy_in_fee"].ToString(), dr["prize"].ToString(), dr["players"].ToString(), dr["status"].ToString(), dr["id"].ToString() });
ControlInvike(listView4, () => listView4.Items.Add(item4));
}
}
}
}
private void LoadFreerollTournaments()
{
ControlInvike(listView5, () => listView5.Items.Clear());
DataSet ds = new DataSet();
ds.ReadXml("http://46.101.5.145/Feeds/freeroll.xml");
ListViewItem item5;
foreach (DataRow dr in ds.Tables["tournament"].Rows)
{
if (dr["play_money"].ToString() != "true")
{
StartDate = dr["start_date"].ToString();
FPPFee = Convert.ToInt32(dr["fpp_fee"]);
if (FPPFee == 0)
{
if (dr["buy_in_fee"].ToString() != "$0 + $0")
{
item5 = new ListViewItem(new string[] { dr["name"].ToString(), StartDate.Substring(0, 10), StartDate.Substring(12, 7), dr["buy_in_fee"].ToString(), dr["prize"].ToString(), dr["players"].ToString(), dr["status"].ToString(), dr["id"].ToString() });
ControlInvike(listView5, () => listView5.Items.Add(item5));
}
}
}
}
}
private void LoadFPPTournaments()
{
ControlInvike(listView6, () => listView6.Items.Clear());
DataSet ds = new DataSet();
ds.ReadXml("http://46.101.5.145/Feeds/all.xml");
ListViewItem item6;
foreach (DataRow dr in ds.Tables["tournament"].Rows)
{
if (dr["play_money"].ToString() != "true")
{
StartDate = dr["start_date"].ToString();
FPPFee = Convert.ToInt32(dr["fpp_fee"]);
if (FPPFee != 0)
{
item6 = new ListViewItem(new string[] { dr["name"].ToString(), StartDate.Substring(0, 10), StartDate.Substring(12, 7), dr["buy_in_fee"].ToString(), dr["prize"].ToString(), dr["players"].ToString(), dr["status"].ToString(), dr["id"].ToString() });
ControlInvike(listView6, () => listView6.Items.Add(item6));
}
}
}
}
private void LoadPlayMoneyTournaments()
{
ControlInvike(listView7, () => listView7.Items.Clear());
DataSet ds = new DataSet();
ds.ReadXml("http://46.101.5.145/Feeds/freeroll.xml");
ListViewItem item7;
foreach (DataRow dr in ds.Tables["tournament"].Rows)
{
if (dr["play_money"].ToString() == "true")
{
StartDate = dr["start_date"].ToString();
FPPFee = Convert.ToInt32(dr["fpp_fee"]);
if (FPPFee == 0)
{
item7 = new ListViewItem(new string[] { dr["name"].ToString(), StartDate.Substring(0, 10), StartDate.Substring(12, 7), dr["buy_in_fee"].ToString(), dr["prize"].ToString(), dr["players"].ToString(), dr["status"].ToString(), dr["id"].ToString() });
ControlInvike(listView7, () => listView7.Items.Add(item7));
}
}
}
}
private void timerUpdateGames_Tick(object sender, EventArgs e)
{
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
}
}
private void pictureBox3_MouseEnter(object sender, EventArgs e)
{
this.Cursor = Cursors.Hand;
}
private void pictureBox3_MouseLeave(object sender, EventArgs e)
{
this.Cursor = Cursors.Arrow;
}
private void pictureBox3_Click(object sender, EventArgs e)
{
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
LoadAllTournaments();
LoadRegularTournaments();
LoadSatelliteTournaments();
LoadSpecialTournaments();
LoadFreerollTournaments();
LoadFPPTournaments();
LoadPlayMoneyTournaments();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
}
else if (!(e.Error == null))
{
MessageBox.Show("Error: " + e.Error.Message);
}
else
{
}
}
}
}
有没有人知道为什么listView会被多次填充?我不介意,但它会在更新时删除这些项目,因此我无法访问列表几分钟。
答案 0 :(得分:1)
我无法分辨你所提供的内容是什么,但引起我注意的一件事是你从RunWorkerAsync
方法再次呼叫timerUpdateGames_Tick
。我找不到任何timerUpdateGames
...是否在其他地方?你有一个正在运行的计时器并导致你的bg工作者一遍又一遍地运行吗?
此外,您的代码非常潮湿(例如,不是D.R.Y)。考虑重构它,以便重复的代码 - 加载锦标赛数据的每个方法中的代码 - 在一个方法中,该方法接受不同事物的参数。这将减少很多错误,并使您的代码更容易进行故障排除。
答案 1 :(得分:0)
认为我发现了我的问题。我删除了以下内容,似乎工作正常:
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);