C#如何在后台线程中运行此代码?

时间:2016-03-03 12:53:27

标签: c# .net forms visual-studio-2015

所以我一直坚持这一点。 (表格申请)

我想让它在“背景”中运行。 我通常用“搜索按钮”来调用它。

到目前为止,我已经读过你无法在另一个线程中访问UI内容了吗?那么我如何处理这个并在加载结果并将其转换为按钮时使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);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您应该在线程上执行'whole'方法。尝试将所有控件创建移动到一个部分,并在GUI线程上调用该部分。最耗费的时间是WebRequests

PSEUDO:类似于:

private void Search_Video_Youtube(string page)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback((state) =>
    {
        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().OfType<SearchResult>();
        List<string> videos = new List<string>();
        Parallel.Foreach(resp.Items, (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);
                    Bitmap 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;
        });
    }, null);

}

答案 1 :(得分:0)

创建一个带有resp

类型参数的委托
public delegate void ListDispatcher(var resp)

请记住,var需要替换为resp的确切类型。

现在在主类中创建一个ListDispatcher引用成员。

public ListDispatcher dispatcher;

并在其调用列表中添加一个新方法。

dispatcher += MyNewMethod;

将新方法定义为

public void MyNewMethod(var resp){

//Move all your controls creation code here

}

通话后删除代码

var resp = listRequest.Execute();

并简单地放在那里

dispatcher(resp);

现在,您可以安全地在单独的帖子中调用Search_Video_Youtube(string page)