我正在获得异常跨线程操作,因为我在线程操作中使用ui var应该如何处理它?

时间:2015-06-17 20:23:36

标签: c# .net multithreading winforms

我改变了这个进展事件:

private void videosInsertRequest_ProgressChanged(IUploadProgress obj)
        {

                toolStripStatusLabel1.Text = obj.Status.ToString();
        }

还有这个事件:

private void videosInsertRequest_ResponseReceived(Video obj)
        {
            toolStripStatusLabel1.Text = obj.Status.UploadStatus;
        }

有时我会得到例外:

跨线程操作无效:控制''从在

上创建的线程以外的线程访问

我应该在此控件上使用BeginInvoke还是在事件之外的其他地方处理它?<​​/ p>

这是我注册活动的地方:

static Video video = null;
        static ulong process = 0;
        private void UploadVideo(string FileName, string VideoTitle, string VideoDescription)
        {
            UserCredential credential;
            using (FileStream stream = new FileStream(@"D:\C-Sharp\Youtube-Manager\Youtube-Manager\Youtube-Manager\bin\Debug\client_secrets.json", FileMode.Open, FileAccess.Read))
            {
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { YouTubeService.Scope.Youtube, YouTubeService.Scope.YoutubeUpload },
                    "user",
                    CancellationToken.None,
                    new FileDataStore("YouTube.Auth.Store")).Result;
            }
            var youtubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
            });
            video = new Video();
            video.Snippet = new VideoSnippet();
            video.Snippet.Title = VideoTitle;
            video.Snippet.Description = VideoDescription;
            video.Snippet.Tags = new string[] { "tag1", "tag2" };
            comboBox1.BeginInvoke((Action)(() =>
            {
                video.Snippet.CategoryId = (comboBox1.SelectedItem as ComboboxItem).Value.ToString();
            }));
            video.Status = new VideoStatus();
            video.Status.PrivacyStatus = "public";

            using (var fileStream = new FileStream(FileName, FileMode.Open))
            {

                const int KB = 0x400;
                var minimumChunkSize = 256 * KB;

                var videosInsertRequest = youtubeService.Videos.Insert(video,
                    "snippet,status", fileStream, "video/*");
                videosInsertRequest.ProgressChanged +=
                    videosInsertRequest_ProgressChanged;
                videosInsertRequest.ResponseReceived +=
                    videosInsertRequest_ResponseReceived;
                videosInsertRequest.ChunkSize = minimumChunkSize * 4;                
                videosInsertRequest.Upload();
            }
        }

然后我有一个按钮点击事件,我开始一个backgroundworker runasync。 然后在DoWork活动中我正在做:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            UploadVideo(FileNameToUpload, uploadVideoTitleTxtBox.Text, uploadVideoDescriptionTxtBox.Text);
        }

现在backgroundworker progresschanged事件是空的,但不知怎的,我应该在我的问题的顶部报告两个事件中的backgroundworker表单。

或者可能在这两个事件中使用BeginInvoke?

我想通过此事件向toolStripStatusLabel1和2报告。

1 个答案:

答案 0 :(得分:2)

ProgressChanged是一个消息系统,用于从后台工作线程获取消息到调用线程。由于您可以访问此管道,因此我将通过定义消息将代码放入ProgressChanged事件中。您可以使用此系统传递多种类型的消息和参数。

这样做的好处是你的后台工作线程保持在预期的范围内。如果您决定使用Invoke路由,那么您将不需要后台工作程序,您可能只使用了一个线程对象而没有额外的管道开销。