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

本文关键字:运行 代码 线程 后台 | 更新日期: 2023-09-27 18:37:15

所以我已经坚持了一段时间了。(表格申请)

我希望它在"后台"运行。我通常用"搜索按钮"来称呼它。

到目前为止,我已经读到您无法在另一个线程中访问 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);
        }
    }
}

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

你应该在线程上执行"whole"方法。尝试将所有控件的创建移动到一个部分,并在 GUI 线程上调用该部分。最耗时的时间将是网络请求

伪:像这样:

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);
}

创建一个接受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)