所以我一直坚持这一段时间。 (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