Search code examples
c#.netwinformsstack-overflow

Why i'm getting exception StackOverFlowException ? And how to solve it?


I added a new form in form1 i have a button click event:

private void button1_Click(object sender, EventArgs e)
        {
            UploadTestingForum utf = new UploadTestingForum();
            utf.Show();
        }

And the new form code i took from example here:

https://github.com/youtube/api-samples/blob/master/dotnet/UploadVideo.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO;
using System.Reflection;
using System.Threading;

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 Youtube_Manager
{
    public partial class UploadTestingForum : Form
    {
        string errors = "";

        public UploadTestingForum()
        {
            InitializeComponent();

            try
            {
                new UploadTestingForum().Run().Wait();
            }
            catch (AggregateException ex)
            {
                foreach (var e in ex.InnerExceptions)
                {
                    //Console.WriteLine("Error: " + e.Message);
                    errors = e.Message;
                }
            }
        }


        private async Task Run()
        {
            UserCredential credential;
            using (var stream = new FileStream(@"D:\C-Sharp\Youtube-Manager\Youtube-Manager\Youtube-Manager\bin\Debug\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 = "Default Video Title";
            video.Snippet.Description = "Default Video Description";
            video.Snippet.Tags = new string[] { "tag1", "tag2" };
            video.Snippet.CategoryId = "22"; // See https://developers.google.com/youtube/v3/docs/videoCategories/list
            video.Status = new VideoStatus();
            video.Status.PrivacyStatus = "unlisted"; // or "private" or "public"
            var filePath = @"D:\tester\20131207_134823.mp4"; // 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:
                    //Console.WriteLine("{0} bytes sent.", progress.BytesSent);
                    label1.Text = progress.BytesSent.ToString();
                    break;
                case UploadStatus.Failed:
                    //Console.WriteLine("An error prevented the upload from completing.\n{0}", progress.Exception);
                    label1.Text = progress.Exception.ToString();
                    break;
            }
        }
        void videosInsertRequest_ResponseReceived(Video video)
        {
            //Console.WriteLine("Video id '{0}' was successfully uploaded.", video.Id);
            label2.Text = video.Id;
        }

        private void UploadTestingForum_Load(object sender, EventArgs e)
        {

        }
    }
}

But once i'm clicking the form1 button i use a breakpoint and i see that it's doing a loop it's doing all the time the lines:

string errors = ""; and new UploadTestingForum().Run().Wait();

Then after some seconds i'm getting exception in the form designer cs file on the line: this.ResumeLayout(false);

An unhandled exception of type 'System.StackOverflowException' occurred in System.Windows.Forms.dll

System.StackOverflowException was unhandled

What i wanted to do is when i click in button1 in form1 it will first show the new form and then execute the code in the new form.


Solution

  • Look at this line:

     new UploadTestingForum().Run().Wait();
    

    Remember that this is part of your form's constructor. When that code runs, it creates another instance of the form and runs its constructor. At that point you'll execute this same code again, which creates another instance and runs its constructor, which executes this code again, which creates another instance of the form....

    Each time the constructor runs another method call goes on the call stack. Since you create a new instance and call the constructor again before the method returns, the stack entries are never cleared/popped. Pretty soon the call stack runs out of space and overflows, hence the StackOverflowException.

    Change the line to this:

    this.Run().Wait();