GetUserByID メソッドに問題があったことが判明し、その後ライブラリが更新され、問題が解消されたように見えますが、スレッドから GUI にアクセスする方法を引き続き学習しました。
TweetInvi ライブラリを使用してアプリケーションを作成しました. ユーザーのフォロワーとフォローを取得します. また、彼らの写真, 写真へのリンクと twitter ID.
次に、返されたリストを反復処理して表示します (すべて別のリストに表示されます)。
このアプリケーションを初めて使用したとき、_Click イベントですべてを実行し、完了するまで UI をフリーズしていました。
コードをバックグラウンド ワーカー スレッドに移動したところ、風変わりな問題が発生しています。
特定のリストに入力しないことを「選択」する場合もあれば、入力する場合もあります。時々、あなたをフォローしているリストを除いて、すべてのリストが正しくロードされます。このリストは、どの友達があなたをフォローしているかをフィルタリングします (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();
}
私の問題は、不可解な奇妙なエラーがまだ一見ランダムに発生していることです。
これがバックグラウンド ワーカー スレッドでリストが更新されていることが原因である場合、バックグラウンド ワーカーを集中的な作業に使用できない場合、バックグラウンド ワーカーは何に使用されますか?
問題をよりよく示しているので、友人のアカウントの 2 つの写真も含めます。最初の問題は、リストに複数回入力することがあり、「バックリストをフォローしていません」は@Theilluminatiを1回だけ返す必要があることです
再び @Theilluminati を返しますが、それを 2 回リストします。
以下のコードをどこでも実行すると、バックグラウンドワーカーが実行されない、つまり、画像/名前/場所を引き戻すがバックグラウンドワーカーが実行されないという問題もあります。実際に実行しようとするとbackgroundworker スレッドの場合、リストは読み込まれません。
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 + ")";
UIスレッドから作業をアンロードできない場合、Backgroundworkerの使用を確認するのに苦労しています。長い投稿で申し訳ありません。読んでくれてありがとう。
修正試行
タスクの実行中に検索ボタンを無効にしましたが、同じ問題が引き続き発生します。
また、タスクが 1 回完了したら、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();
私は解決策として両方の答えを試しましたが、どちらも重大度の異なる同じ問題につながります。名前/画像などを取得するコードのコメントを外すと、バックグラウンドワーカーの実行がブロックされるという問題にまだ悩まされています。どこから実行されても構いません。