2017-04-18 3 views
0

Ich habe ein YouTube-Uploader, und ich bin ein Video aus einer Audiodatei erzeugen, die gut funktioniert, aber wenn ich auf Youtube hochladen läuft das Programm noch, wenn ich versuche zu warten für sie das Hochladen zu beenden, bevorFunktionen werden nicht vor dem Start der nächsten

Hier Wiederholung erzeugen ich ein Video:

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

Wie ich Youtube bin Hochladen:

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

Der Gerechte Hintergrund Arbeiter läuft core();

Wenn es die Funktion erreicht

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

Es beginnt das Hochladen aber startet die Kernfunktion zu wiederholen wieder so ein weiteres Video zu erzeugen, bevor das Video hat hochgeladen .... Wenn ich

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

Dann hält das Programm einfach an und wartet unablässig, bis ich das Programm schließe. Wie kann ich warten, bis die Upload-Klasse/Methode beendet ist, bevor ich mit der Fore-Schleife in der Kernmethode fortfahre?

Um den Typ, der antwortete, wenn ich warten, bevor die neue Hochladen hinzufügen ... es gibt mir:

Severity Code Beschreibung Projektdatei Zeilenunterdrückungszustand Fehler CS4033 Die ‚erwarten‘ Operator kann nur sein innerhalb einer asynchronen Methode verwendet. Erwägen Sie, diese Methode mit dem Modifizierer 'async' zu markieren, und ändern Sie den Rückgabetyp in 'Task'. articletoyoutube C: \ Benutzer \ Laptop \ Dokumente \ Visual Studio 2017 \ Projects \ articletoyoutube \ articletoyoutube \ Form1.cs 254 Aktive

+3

aha - das alte - wie kann ich eine asynchrone Methode synchron aufrufen. Die allgemein akzeptierte Antwort ist "tue es nicht" - googeln nach "asynchronen Methoden synchrone aufrufen" für lange Diskussionen – pm100

+0

Es klingt wie Sie Async/erwarten sollten – sniels

+0

Ich bin fast 100% certine dass 'Form1 Kern = neue Form1();' in 'UploadVideo' ist ein Fehler, der darauf wartet, dass Sie nie 'new Form1()' aufrufen müssen Sie sollten eine existierende Instanz übergeben (das hat nichts mit Ihrem Problem zu tun) –

Antwort

1

Stellen Sie sicher, das Asynchron-Schlüsselwort auf Ihre Methoden verwendet wird, und das await Schlüsselwort für die Aufgaben verwenden .

Zum Beispiel:

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

Sie benötigen eine Call-Stack await den ganzen Weg zu verwenden, bis zu dem Ihr Event-Handler ist, wird dies viele Ihrer Methoden ausgetauscht werden müssen.

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

Hinweis, mit Asynchron/erwarten nicht mit BackgroundWorker funktioniert Sie mit Task.Run und CancellationToken zu signalisieren Stornierung wechseln müssen.

+0

Vielen Dank für Ihre Hilfe, meine ich erhalte 1 Fehlermeldung, Severity \t-Code \t Beschreibung \t Projekt \t Datei \t Linie \t Suppression Zustand Fehler \t CS1501 \t Keine Überlastung für die Methode 'Kern' nimmt 1 Argumente \t articletoyoutube \t C: \ Benutzer \ Laptop \ Dokumente Visual Studio 2017 \ Projects \ \ articletoyoutube \ articletoyoutube \ Form1.cs Aktiv – 4334738290

+0

Ja, weil ich änderte es, um ein CancellationToken zu nehmen, wenn Sie Ihren Code annullieren möchten, müssen Sie kooperative Löschung implemente. [Hier ist ein guter Artikel] (https://msdn.microsoft.com/en-us/library/dd997364 (v = vs.110) .aspx), der erklärt, was Sie mit diesem CancellationToken tun müssen. –

Verwandte Themen