2

I'm trying to use TweetSharp from a static class (called TitterHandler) so theoretically I can swap it out later.

The example suggests using Dispatch.BeginInvoke so when the UI is updated it is done using the UI thread.

I would like to just load data into the model, although admittedly this will trigger an OnPropertyChanged event which will update the UI. Since this is from a static method I use System.Windows.Deployment.Current.Dispatcher.BeginInvoke.

However it keeps crashing with an 'Object not set to a reference ' exception. I have fairly limited understanding of threads but from what I gather

  • The UI thread needs to update the UI but the main thread may fire an event which is then picked up by the UI thread - to test this I assign to a static variable totally separate from the UI (TweetCache) but the app still crashes
  • The thread may be garbage collected if there are no references to it. I placed a reference (Thread) on the class but still it crashes.

I am out of ideas, here is the code ...

public class TwitterHandler
{

    public static TwitterService Service = new TwitterService(AppConfig.TwitterConsumerKey, AppConfig.TwitterConsumerSecret);

    internal static void LoadTweetsFromWeb()
    {
        TwitterHandler.Service.AuthenticateWith(AppConfig.TwitterToken, AppConfig.TwitterTokenSecret);
        TwitterHandler.Service.ListTweetsOnUserTimeline(new ListTweetsOnUserTimelineOptions() 
            { ScreenName = AppConfig.NewsBrandingTwitterHandle, }, 
            TwitterHandler.OnTweetsLoaded);
    }


    // Put this here to maintain a refrence to the thread to avoid GC
    public static DispatcherOperation Thread;

    // A 'thread external' reference with no onward events that trigger UI changes
    public static List<Tweet> TweetCache;

    public static void OnTweetsLoaded(IEnumerable<TwitterStatus> statuses, TwitterResponse res)
    {
        if (res.StatusCode == HttpStatusCode.OK)
        {
            TwitterHandler.Thread = System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                List<Tweet> tweets = new List<Tweet>();
                foreach (TwitterStatus status in statuses)
                {
                    tweets.Add(new Tweet()
                    {
                        Content = status.Text,
                        UrlString = status.Place.Url,
                    });
                }
                if (tweets.Count > 0)
                {
                    // App.Tweets = tweets;
                    // TweetCache raises no 'PropertyChanged' event
                    TwitterHandler.TweetCache = tweets;
                }

            });
        }


    }




}
Brendan
  • 18,771
  • 17
  • 83
  • 114
  • 1
    Where (at which line) does it throw the exception? – rene Feb 12 '14 at 10:14
  • The exception is really vague (missing a 'pdb' object), when I stepped through it went dead at the `foreach` loop when adding statuses ... – Brendan Feb 12 '14 at 10:16
  • `status.Place` is guaranteed to be not null? – rene Feb 12 '14 at 10:18
  • Damnit you are right. The `Place` parameter is not what I though it was and is null - It's really annoying that the debugger stops giving useful info inside a thread - make an answer and I'll close out the question ... – Brendan Feb 12 '14 at 10:36
  • 1
    http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it – Soner Gönül Feb 12 '14 at 11:09
  • @Soner Heh that'd a great SO question. I know what Null Reference is but the problem with threads is that I automatically assume it is something deeper 'because threads' and the FUD surrounding them ... – Brendan Feb 12 '14 at 11:39

1 Answers1

2

Our shared debug powers revealed that status.Place is null.

(other options could be but are less likely: the caller disposes statuses member)

rene
  • 41,474
  • 78
  • 114
  • 152