2017-04-18 33 views
0

我有一个YouTube上传,我从音频文件生成的视频,工作正常,但是当我上传到YouTube时,程序仍然运行时,当我试图等待为它重复功能没有完成,然后开始下一个

这里之前完成上传我产生了一个视频:

private void button2_Click(object sender, EventArgs e) 
    { 
     if (status.Text == "Stopped") 
     { 
      if (!generatearticle.IsBusy) 
      { 
       // started 
       status.Text = "Started"; 
       status.ForeColor = System.Drawing.Color.Green; 
       start.Text = "Stop Generating"; 
       generatearticle.RunWorkerAsync(); 
      } 
     } 
     else 
     { 
      if(generatearticle.IsBusy) 
      { 
       generatearticle.CancelAsync(); 
       // started 
       status.Text = "Stopped"; 
       status.ForeColor = System.Drawing.Color.Red; 
       start.Text = "Start Generating"; 
      } 
     } 
    } 

    private void core() 
    { 
     // generate audio 
     int i = 0; 
     for (int n = 1; n < co; n++) 
     { 
      // generate video and upload to 
      // youtube, this generates, but 
      // when uploading to youtube this for 
      // loop carries on when I want it to 
      // upload to youtube first before carrying on 
      generatevideo(image, articlename); 
     } 
    } 

    private void generateVideo(string images, String articlename) 
    { 
     //generate the video here, once done upload 
     {code removed, this just generates a video, nothing important} 

     // now upload (but I want it to finish before repeating the core() function 
     try 
      { 
       new UploadVideo().Run(articlename, file); 

      } 
      catch (AggregateException ex) 
      { 
       foreach (var e in ex.InnerExceptions) 
       { 
        ThreadSafe(() => 
        { 
         this.Invoke((MethodInvoker)delegate 
         { 
          status.Text = e.Message; 
          status.ForeColor = System.Drawing.Color.Red; 
         }); 
        }); 
       } 
      } 
    } 

如何我上传到YouTube:

using System; 
using System.IO; 
using System.Reflection; 
using System.Threading; 
using System.Threading.Tasks; 
using Google.Apis.Auth.OAuth2; 
using Google.Apis.Services; 
using Google.Apis.Upload; 
using Google.Apis.Util.Store; 
using Google.Apis.YouTube.v3; 
using Google.Apis.YouTube.v3.Data; 

namespace articletoyoutube 
{ 
    /// <summary> 
    /// YouTube Data API v3 sample: upload a video. 
    /// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher. 
    /// See https://code.google.com/p/google-api-dotnet-client/wiki/GettingStarted 
    /// </summary> 
    class UploadVideo 
    { 
     // to access form controlls 
     Form1 core = new Form1(); 

     public async Task Run(string articlename, string filelocation) 
     { 
      UserCredential credential; 
      using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read)) 
      { 
       credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets, 
        // This OAuth 2.0 access scope allows an application to upload files to the 
        // authenticated user's YouTube channel, but doesn't allow other types of access. 
        new[] { 
         YouTubeService.Scope.YoutubeUpload 
        }, 
        "user", 
        CancellationToken.None 
       ); 
      } 


      var youtubeService = new YouTubeService(new BaseClientService.Initializer() 
      { 
       HttpClientInitializer = credential, 
       ApplicationName = Assembly.GetExecutingAssembly().GetName().Name 
      }); 

      var video = new Video(); 
      video.Snippet = new VideoSnippet(); 
      video.Snippet.Title = articlename; 
      video.Snippet.Description = "News story regarding" + articlename; 
      video.Snippet.Tags = new string[] { 
       "news", 
       "breaking", 
       "important" 
      }; 
      video.Snippet.CategoryId = "25"; // See https://developers.google.com/youtube/v3/docs/videoCategories/list 
      video.Status = new VideoStatus(); 
      video.Status.PrivacyStatus = "public"; // or "private" or "public" 
      var filePath = filelocation; // Replace with path to actual movie file. 

      using (var fileStream = new FileStream(filePath, FileMode.Open)) 
      { 
       var videosInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", fileStream, "video/*"); 
       videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged; 
       videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived; 

       await videosInsertRequest.UploadAsync(); 
      } 
     } 

     void videosInsertRequest_ProgressChanged(Google.Apis.Upload.IUploadProgress progress) 
     { 
      switch (progress.Status) 
      { 
       case UploadStatus.Uploading: 
        core.prog_up.Text = "{0} bytes sent." + progress.BytesSent; 
        break; 

       case UploadStatus.Failed: 
        core.status.Text = "An error prevented the upload from completing.\n{0}" + progress.Exception; 
        core.status.ForeColor = System.Drawing.Color.Red; 
        break; 
      } 
     } 

     void videosInsertRequest_ResponseReceived(Video video) 
     { 
      core.prog_up.Text = "Video id '{0}' was successfully uploaded." + video.Id; 
     } 
    } 
} 

的后台工作只是运行core();

当它到达功能

new UploadVideo().Run(articlename, file); 

它开始上传,但再次开始重复的核心功能由此生成的视频前,另一视频上传....如果我使用

new UploadVideo().Run(articlename, file).Wait(); 

然后,程序停止并等待,直到关闭程序,我如何才能继续使用核心方法中的前循环来完成Upload类/方法?

要回答谁的家伙,当我添加新的上传前等待......它给了我:

严重性代码说明项目文件的线路抑制状态 错误CS4033在“等待”操作只能是在异步 方法中使用。考虑用“异步”修饰符标记此方法,并将其返回类型更改为 “任务”。 articletoyoutube C:\用户\笔记本\文档\ Visual Studio的 2017 \项目\ articletoyoutube \ articletoyoutube \ Form1.cs的254主动

+3

aha - 旧 - 我怎样才能同步调用异步方法。普遍接受的答案是'不这样做' - 谷歌为“调用异步方法同步”长时间的讨论 – pm100

+0

这听起来像你应该使用异步/等待 – sniels

+0

我几乎100%证明'Form1核心=新的Form1();' 'UploadVideo'是一个等待发生的错误,你永远不需要调用'new Form1()'你应该传递一个现有的实例(这与你的问题无关) –

回答

1

确保async关键字是在你的方法使用,使用的await关键字的任务。

例如:

private async Task core() 
{ 
    // generate audio 
    int i = 0; 
    for (int n = 1; n < co; n++) 
    { 
     await generatevideo(image, articlename); 
    } 
} 

private async Task generateVideo(string images, String articlename) 
    { 
     //generate the video here, 
     try 
      { 
       var uploadVideo = new UploadVideo(); 
       await uploadVideo.Run(articlename, file); 

      } 
      catch (AggregateException ex) 
      { 
       foreach (var e in ex.InnerExceptions) 
       { 
        ThreadSafe(() => 
        { 
         this.Invoke((MethodInvoker)delegate 
         { 
          status.Text = e.Message; 
          status.ForeColor = System.Drawing.Color.Red; 
         }); 
        }); 
       } 
      } 
    } 
0

您需要使用await一路上涨调用栈到您的事件处理程序,这将需要改变你的许多方法。

private async Task core() 
{ 
    // generate audio 
    int i = 0; 
    for (int n = 1; n < co; n++) 
    { 
     // generate video and upload to 
     // youtube, this generates, but 
     // when uploading to youtube this for 
     // loop carries on when I want it to 
     // upload to youtube first before carrying on 
     await generatevideo(image, articlename); 
    } 
} 

private async Task generateVideo(string images, String articlename) 
{ 
    //generate the video here, once done upload 
    {code removed, this just generates a video, nothing important} 

    // now upload (but I want it to finish before repeating the core() function 
    try 
     { 
      await new UploadVideo().Run(articlename, file); 

     } 
     catch (AggregateException ex) 
     { 
      foreach (var e in ex.InnerExceptions) 
      { 
       ThreadSafe(() => 
       { 
        this.Invoke((MethodInvoker)delegate 
        { 
         status.Text = e.Message; 
         status.ForeColor = System.Drawing.Color.Red; 
        }); 
       }); 
      } 
     } 
} 

注意,使用异步/等待不BackgroundWorker工作,你需要切换到使用Task.RunCancellationToken信号取消。

Task _backgroundWork; 
CancellationTokenSource _cts; 

private void button2_Click(object sender, EventArgs e) 
{ 
    if (status.Text == "Stopped") 
    { 
     if (!generatearticle.IsBusy) 
     { 
      // started 
      status.Text = "Started"; 
      status.ForeColor = System.Drawing.Color.Green; 
      start.Text = "Stop Generating"; 
      _cts = new CancellationTokenSource(); 
      _backgroundWork = Task.Run(() => core(_cts.Token), _cts.Token); 
     } 
    } 
    else 
    { 
     if(!_backgroundWork.IsCompleted) 
     { 
      _cts.Cancel(); 
      // started 
      status.Text = "Stopped"; 
      status.ForeColor = System.Drawing.Color.Red; 
      start.Text = "Start Generating"; 
     } 
    } 
} 
+0

感谢你的帮助,我的我得到1个错误说严重\t代码\t说明\t项目\t文件\t线\t抑制国家 错误\t CS1501 \t无重载方法 '核心' 需要1个参数\t articletoyoutube \t C:\用户\笔记本\文档\ Visual Studio的2017年\项目\ articletoyoutube \ articletoyoutube \ Form1.cs中活动 – 4334738290

+0

是啊,因为我将其更改为取消CancellationToken,如果您想要取消您的代码,则需要执行取消协作。 [这里是一篇很好的文章](https://msdn.microsoft.com/en-us/library/dd997364(v = vs.110).aspx),它解释了你需要用CancellationToken做什么。 –

相关问题