gpt4 book ai didi

c# - BackgroundWorker 奇怪的问题

转载 作者:太空宇宙 更新时间:2023-11-03 21:34:28 25 4
gpt4 key购买 nike

原来是 GetUserByID 方法有问题,然后更新了库,问题似乎已经消失,仍然学会了如何更好地离线访问 GUI。

我使用 TweetInvi 库编写了一个应用程序,它检索用户的关注者和关注者,还有他们的图片、图片链接和推特 ID。

然后它遍历返回的列表并显示它们(全部在不同的列表中)

现在,当我第一次开始使用这个应用程序时,我让一切都在 _Click 事件上运行,当然我会卡住 UI 直到它完成。

我现在已将代码移至后台线程,它导致了一些古怪的问题。

有时它会“选择”不填充某些列表,有时它会。有时它会正确加载所有列表,除了“关注你”列表,它会过滤你的哪些 friend 正在关注你(使用 If 语句过滤掉已验证的帐户)

起初我读到尝试在单独的线程上更新 UI 会导致奇怪的错误,所以我删除了除它填充的列表之外的所有 UI 控件更改。

 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;


//user name retrieved from text box, rest of this method will pull various bits of data back

var username = e.Argument.ToString();
var user = User.GetUserFromScreenName(username);



Properties.Settings.Default.LastHandle = boxUsername.Text;
Properties.Settings.Default.Save();



var usersTweets = user.GetUserTimeline(Convert.ToInt32(txtTweetAmount.Text)).ToList();

foreach (var userTweet in usersTweets)
{
lstSearchTweetList.Invoke((MethodInvoker)delegate
{
var searchList = lstSearchTweetList.Items.Add(userTweet.Text);
searchList.SubItems.Add(userTweet.CreatedAt.ToString());
});
}


var show = user.GetFollowers(500).ToList();


foreach (var friend in show)
{

string screenName = "@" + friend.ScreenName;
lstFriend.BeginInvoke((MethodInvoker)delegate
{
lstFriend.Items.Add(screenName); // runs on UI thread
});

}

var friends = user.GetFriends(500);
var followers = user.GetFollowers(500);


var result2 = followers.Where(follower => friends.All(friend => follower.Name != friend.Name));
int i2 = 0;
foreach (var res2 in result2)
{
string screenName = "@" + res2.ScreenName;
lstFollowingChecker.BeginInvoke((MethodInvoker)delegate
{
lstFollowingChecker.Items.Add(screenName);
});
i2++;
// lblFollowBackAmount.Text = Convert.ToString(i2);
}
var result = friends.Where(friend => followers.All(follower => friend.Name != follower.Name));

//lblFriendCount.Text = "(" + result.Count().ToString() + ")";
int i1 = 0;
foreach (var res in result)
{
if (res.Verified != true)
{
string screenName = "@" + res.ScreenName;
lstFollowerChecker.BeginInvoke((MethodInvoker)delegate
{
lstFollowerChecker.Items.Add(screenName);
});

i1++;
// lblCheckerCount.Text = Convert.ToString(i1);
}
}



backgroundWorker1.ReportProgress(1,username);
}

调用 RunWorkerAsync() 的函数

private void btnFind_Click(object sender, EventArgs e)
{

//start backgroundworker and clear friends and search lists
pctProgressBar.Visible = true;

lstFriend.Items.Clear();
lstSearchTweetList.Items.Clear();
lstFollowerChecker.Items.Clear();
lstFollowingChecker.Items.Clear();
lstFriend.Items.Clear();
lstSearchTweetList.Items.Clear();

if (txtTweetAmount.Text == "")
{
txtTweetAmount.Text = "20";
}

backgroundWorker1.RunWorkerAsync();

}

我的问题是奇怪的无法解释的错误仍然看似随机发生。

如果这是由于列表在后台工作线程中更新引起的,如果我不能用它来做密集型工作,后台工作线程有什么用

我还将附上两张 friend 帐户的图片,因为它可以更好地说明问题,因此处理等内容将被删除。第一个问题是它有时会多次填充一个列表,而“不关注你返回列表”应该只返回一次@Theilluminati Same Screen first Time

它再次返回@Theilluminati,但列出了两次。 Same Screen Second time

还有一个问题,如果我在任何地方运行下面的代码,后台工作程序不会运行,也就是说,它会拉回图片/名称/位置,但后台工作程序不会运行,如果我尝试这样做在实际的后台工作线程中,列表将不会填充。

   var username = boxUsername.Text;
var user = User.GetUserFromScreenName(username);
//string ImageURL = user.ProfileImageUrl;
//string biggerImageURL = ImageURL.Replace("_normal", "");
//txtImageURL.Text = biggerImageURL;
//pctDisplaypicture.ImageLocation = biggerImageURL;
//txtTwitterID.Text = user.Id.ToString();
//lblFriendCount.Text = "(" + user.FollowersCount + ")";

任何帮助都将不胜感激,如果 Backgroundworker 无法从 UI 线程卸载工作,我现在正在努力查看它的使用,很抱歉这篇文章很长,感谢阅读。

修复尝试

我在任务运行时禁用了查找按钮,但仍然出现同样的问题。

我也尝试过使用 if(working.Cancellationpending == true) 在任务完成一次后跳出循环。

我已分别将列表 foreach 循环更改为以下内容,并将用户名作为变量传递而不是从控件中提取它,问题似乎变得更糟了,现在根本没有列表填充。

lstSearchTweetList.Invoke((MethodInvoker)delegate
{
lstSearchTweetList.Items.Add(userTweet.Text).SubItems.Add(userTweet.CreatedAt.ToString());
});

backgroundWorker1.RunWorkerAsync(boxUsername.Text);

var username = e.Argument.ToString();

我已经尝试了这两个答案作为解决方案,但仍然会导致严重程度不同的相同问题,我仍然遇到取消注释代码以检索名称/图片等的问题仍然会阻止后台工作程序运行。无论它从哪里运行。

最佳答案

您可能需要在您尝试在后台线程上更新的列表控件上使用 Invoke 方法,如下所示:

    string  screenName = "@" + friend.ScreenName;
lstFriend.Invoke((MethodInvoker)delegate {
lstFriend.Items.Add(screenName); // runs on UI thread
});

多线程可能会遇到的一个问题是,当您尝试从多个线程访问共享资源(集合、文件等)时,可能会发生死锁和竞争条件。为了安全地执行此操作,在这种情况下将创建一个锁定对象并锁定正在访问共享资源的代码。这样一次只能访问一个资源。

    //defined globally
object _MyLockingObject = new object();

并在某个方法中锁定列表:

    lock(_MyLockingObject)
{
myList.Add(item);
}

关于c# - BackgroundWorker 奇怪的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22438761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com