Hello everyone,

I am working on a C# app that uses the YouTube .NET API but have come up with an issue, and I'm not sure if its the .NET Wrapper or just something I'm Doing.

Ok heres the problem, I request the list of videos the logged in user has and I get it back as a IEnumerable<video>, now from everywhere I read, IEnumerable is supposed to be better then List<T> and what not. One site showed an example of 1,000,000 Entries in IEnumerable<int> could be iterated in just over 1 second. My problem is that i have 458 Entries and its taking 45 seconds or more to populate my listview or use ElementAt() to get the video at the index of the listview (the farther down the longer, 54 being selecting the lastitem). So what am i doing wrong? or is it something with the <Video> that the IEnumerable is full of?

heres is the entire code that I'm using. including a commented part where i was just testing the time to iterate the IEnumerable.

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using BrightIdeasSoftware;
using Google.GData.Client;
using Google.GData.YouTube;
using Google.YouTube;

namespace YTManager
{
    public partial class frmVideos : Form
    {
        private readonly mdiMain _parent;
        private readonly YouTubeRequest _ytRequest;
        //private List<Video> _videos = new List<Video>();
        private IEnumerable<Video> _videos;
        private int _videoCount;

        public frmVideos(string authToken, mdiMain parent)
        {
            InitializeComponent();
            _parent = parent;
            var settings = new YouTubeRequestSettings(mdiMain.APPLICATION_NAME, mdiMain.DEVELOPER_KEY);
            settings.AutoPaging = true;
            _ytRequest = new YouTubeRequest(settings);
            _ytRequest.Service.SetAuthenticationToken(authToken);
        }

        public void initVideos()
        {
            _parent.updateStatusBar("Loading your videos");

            Debug.WriteLine("Getting Videos: " + DateTime.Now);
            _videos = getVideos();
            Debug.WriteLine("Got Feeds: " + DateTime.Now);

            var stopWatch = new Stopwatch();
            /*
            try
            {
                stopWatch.Start();
                foreach (var video in _videos)
                {
                    Debug.Print(video.Title);
                }
                stopWatch.Stop();
            }
            finally
            {
                MessageBox.Show(stopWatch.ElapsedMilliseconds.ToString());
            
            }
             * */
            //=======================//
            try
            {
                Cursor = Cursors.WaitCursor;
                stopWatch.Start();
                oblstVideos.SetObjects(_videos);
            }
            finally
            {
                stopWatch.Stop();
                Cursor = Cursors.Default;
            }
            _parent.updateStatusBar(string.Format("SetObjects()time: {0} items in {1}ms", oblstVideos.Items.Count, stopWatch.ElapsedMilliseconds));
            
        }

        private static string checkNA(string value, string message)
        {
            return value == "-1" ? message : value;
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private IEnumerable<Video> getVideos()
        {
            Feed<Video> feed = null;

            try
            {
                feed = _ytRequest.GetVideoFeed("default");
                _videoCount = feed.TotalResults;
            }
            catch
            {
                MessageBox.Show("Error while retrieving your videos!", "YT Manager", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return feed != null ? feed.Entries : null;
        }

        private void oblstVideos_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            var player = new frmPlayer(_videos.ElementAt(oblstVideos.SelectedItem.Index));
            player.Show();
        }

        private void oblstVideos_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            var video = _videos.ElementAt(e.Item.Index);

            pcbThumbnail.ImageLocation = video.Thumbnails[0].Url;
            txtTitle.Text = video.Title;
            txtDescription.Text = video.Description;
            txtTags.Text = video.Keywords;
            chkPrivate.Checked = video.Private;
        }

    }
}

any help would be appreciated

Thank You

Recommended Answers

All 7 Replies

I suspect it is having to make a call to YouTube on each iteration of the IEnumerable.

Can you show the code for your Video class?

Momerath's probably right... How long does it usually take for your getVideos method to run? I didn't see code for that. I'd step through it with a debugger, and look at exactly what properties are being returned in that Video object.

I added some timers to the initVideos() function

public void initVideos()
        {
            _parent.updateStatusBar("Loading your videos");
                       
            Cursor = Cursors.WaitCursor;

            _stopWatch.Start();
            _videos = getVideos();
            _stopWatch.Stop();

            Debug.Print(string.Format("_videos = getVideos(): {0}ms", _stopWatch.ElapsedMilliseconds));
            _stopWatch.Reset();

            try
            {
                _stopWatch.Start();
                oblstVideos.SetObjects(_videos);
                _stopWatch.Stop();
            }
            catch(Exception e)
            {
                MessageBox.Show("Error: " + e.Message);
            }
            
            Cursor = Cursors.Default;

            Debug.Print(string.Format("oblstVideos.SetObjects(_videos);: {0}ms", _stopWatch.ElapsedMilliseconds));
            _stopWatch.Reset();

            _parent.updateStatusBar(string.Format("Loaded {0} Video(s)", _videoCount));
        }

and the output was

_videos = getVideos(): 2656ms
oblstVideos.SetObjects(_videos);: 46045ms

What type is oblstVideos? I dont recall a standard listview having a SetObjects method.

It's ObjectListView from http://objectlistview.sourceforge.net/cs/index.html thought the normal listview was the thing being slow, and i didn't want to write the code to do column sorting.


I do need to say that i did some research last night and downloaded the YouTube API source so i could step through the process and find what was causing it to go so slow. And i found that it is in fact, downloading the feed any time you access the Video.Entries IEnumerable. So I guess Ill have to live with it, because I want it to get all the video when ever you open the form. for for now i just read it into a List and everything goes fast after that, just uses a lot of memory (about 24MB for 468 items in the list).

I did notice however, that longest pause seems to be logging into YouYube. Because you can only get 50 videos per feed (which i think is stupid cause now they have to handle 9 requests inserted of 1), and every request it sends the auth token and pauses for about 1.5 seconds then processing the feed takes only about 1-2 seconds.

So, I might need to post over on there board to see if theres a faster way, unless anyone here know.

Thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.