2017-04-18 83 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做什麼。 –

相關問題