所以我一直堅持這一段時間。 (Forms應用程序)C#如何在後臺線程中運行此代碼?
我希望在「背景」中運行它。 我通常用「搜索按鈕」調用它。
到目前爲止,我讀過你不能在另一個線程訪問UI的東西?那麼我怎樣才能解決這個問題,並在加載結果並將它們轉換爲按鈕時使用戶界面可訪問? 對於剛剛開始使用C#的人來說,是否有任何簡單的方法可以做到這一點?下面
代碼:
private void Search_Video_Youtube(string page)
{
YouTubeService youtube = new YouTubeService(new BaseClientService.Initializer()
{
ApplicationName = this.GetType().ToString(),
ApiKey = "*MyApiKeyGoesHere*",
});
var listRequest = youtube.Search.List("snippet");
listRequest.Q = Youtube_SearchVideo_Box.Text;
listRequest.MaxResults = 50;
listRequest.Type = "video";
listRequest.PageToken = nextPageToken;
video_results_vids = video_results_vids + 50;
var resp = listRequest.Execute();
List<string> videos = new List<string>();
foreach (SearchResult result in resp.Items)
{
switch (result.Id.Kind)
{
case "youtube#video":
PictureBox picturebox = new PictureBox();
picturebox.Height = 100;
picturebox.Width = 100;
picturebox.BorderStyle = BorderStyle.None;
picturebox.SizeMode = PictureBoxSizeMode.StretchImage;
string template2 = "http://i3.ytimg.com/vi/{0}{1}";
string data2 = result.Id.VideoId.ToString();
string quality2 = "/default.jpg";
string messageB = string.Format(template2, data2, quality2);
var request = WebRequest.Create(messageB);
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
picturebox.Image = Bitmap.FromStream(stream);
}
flowLayoutPanel1.Controls.Add(picturebox);
listnumber += 1;
Button button = new Button();
button.Text = listnumber.ToString() + " " + result.Snippet.Title.ToString();
button.Tag = result.Id.VideoId;
button.TextImageRelation = TextImageRelation.ImageBeforeText;
button.FlatStyle = FlatStyle.Flat;
button.ForeColor = Color.LightSteelBlue;
button.BackColor = Color.SteelBlue;
button.Width = (flowLayoutPanel1.Width - 150);
button.TextAlign = ContentAlignment.MiddleLeft;
button.Height = 100;
button.Font = new Font(button.Font.FontFamily, 10);
button.Click += (s, e) => {
Youtube_video_Player_hider.Visible = false;
var a = result.Id.VideoId;
string template = "https://www.youtube.com/v/{0}{1}";
string data = a.ToString();
string quality = Video_Quality;
string messagea = string.Format(template, data, quality);
axShockwaveFlash1.Movie = messagea;
axShockwaveFlash1.Play();
};
flowLayoutPanel1.Controls.Add(button);
break;
}
}
nextPageToken = resp.NextPageToken;
toolStripStatusLabel1.Text = "Status : Idle";
toolStripStatusLabel2.Text = "Results : " + video_results_vids;
}
任何幫助是值得歡迎的,但請詳細解釋一下,因爲我很新的C#,但我有一個基本的編程知識。 編輯:謝謝Jeroen van langen(下面的答案)我找到了答案。如果你看到任何我可以做得更好,隨時指出它,我在這裏學習:))
編輯: 當前的代碼是現在:
// At using Stuff
using ExtensionMethods;
private void Search_Video_Youtube(string page)
{
ThreadPool.QueueUserWorkItem(new WaitCallback((state) =>
{
YouTubeService youtube = new YouTubeService(new BaseClientService.Initializer()
{
ApplicationName = this.GetType().ToString(),
ApiKey = "ThisIsTheApiKeyYouTubeWantsForAnyoneWondering",
});
var listRequest = youtube.Search.List("snippet");
listRequest.Q = Youtube_SearchVideo_Box.Text;
listRequest.MaxResults = 50;
listRequest.Type = "video";
listRequest.PageToken = nextPageToken;
video_results_vids = video_results_vids + 50;
var resp = listRequest.Execute();
List<string> videos = new List<string>();
Parallel.ForEach(resp.Items, (SearchResult result) =>
{
switch (result.Id.Kind)
{
case "youtube#video":
string template2 = "http://i3.ytimg.com/vi/{0}{1}";
string data2 = result.Id.VideoId.ToString();
string quality2 = "/default.jpg";
string messageB = string.Format(template2, data2, quality2);
Image image;
var request = WebRequest.Create(messageB);
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
image = Bitmap.FromStream(stream);
}
listnumber += 1;
this.Invoke(() =>
{
PictureBox picturebox = new PictureBox();
picturebox.Height = 100;
picturebox.Width = 100;
picturebox.Image = image;
picturebox.BorderStyle = BorderStyle.None;
picturebox.SizeMode = PictureBoxSizeMode.StretchImage;
flowLayoutPanel1.Controls.Add(picturebox);
Button button = new Button();
button.Text = listnumber.ToString() + " " + result.Snippet.Title.ToString();
button.Tag = result.Id.VideoId;
button.TextImageRelation = TextImageRelation.ImageBeforeText;
button.FlatStyle = FlatStyle.Flat;
button.ForeColor = Color.LightSteelBlue;
button.BackColor = Color.SteelBlue;
button.Width = (flowLayoutPanel1.Width - 150);
button.TextAlign = ContentAlignment.MiddleLeft;
button.Height = 100;
button.Font = new Font(button.Font.FontFamily, 10);
button.Click += (s, e) =>
{
Youtube_video_Player_hider.Visible = false;
var a = result.Id.VideoId;
string template = "https://www.youtube.com/v/{0}{1}";
string data = a.ToString();
string quality = Video_Quality;
string messagea = string.Format(template, data, quality);
axShockwaveFlash1.Movie = messagea;
axShockwaveFlash1.Play();
};
flowLayoutPanel1.Controls.Add(button);
});
break;
}
nextPageToken = resp.NextPageToken;
this.Invoke(() =>
{
toolStripStatusLabel1.Text = "Status : Idle";
toolStripStatusLabel2.Text = "Results : " + video_results_vids;
});
});
}));
}
類內容:
using System;
using System.Windows.Forms;
namespace ExtensionMethods
{
public static class MyExtensions
{
public static void Invoke(this Control control, Action action)
{
control.Invoke((Delegate)action);
}
}
}
那麼最耗時的部分似乎是加載50個按鈕。 我有我的代碼像http://stackoverflow.com/questions/35763971/c-sharp-net-youtube-v3-api-issue-listing-items-to-control/35764318#35764318之前,這給了它自己的問題= \。並且在GUI線程中,我認爲這就是通常正確執行的地方?到目前爲止,C#有點讓人困惑,所以對於noob問題感到抱歉。 – R593B
您不能直接從另一個線程訪問由UI線程創建的對象。但是,您可以**跳轉線程,或者對UI線程執行'BeginInvoke'調用,以更新/修改其控件。很多互聯網上的例子... :-) – code4life