I have been playing with Linq to twitter and, after much pain, have finally got some results coming back. This code is working...
public IList<ITweet> BuildForAuthor(string author)
{
var result = new List<ITweet>();
context = context != null ? context : new TwitterContext(_auth);
var tweets = (from tweet in context.Status
where tweet.Type == StatusType.User &&
tweet.ScreenName == author
select tweet).Take(4).ToList();
if (tweets != null)
{
foreach (var tweet in tweets)
{
if (!tweet.Retweeted)
{
result.Add(new Tweet
{
Author = tweet.ScreenName,
Text = tweet.Text
});
}
else
{
result.Add(new Tweet
{
Author = tweet.RetweetedStatus.User.ScreenNameResponse,
Text = tweet.RetweetedStatus.Text,
Retweet = true,
RetweetedBy = tweet.ScreenName
});
}
}
}
return result;
}
The problem I have with this is that it's not asynchronous (and it needs error handling). I am a little at sea with async as it's completely new to me (been doing it in JavaScript for years so the concept is understood). The documentation for LinqToTwitter insists it must be async but all the async examples just don't run for me.
This is just plain wrong...
public IList<ITweet> BuildForAuthor(string author)
{
var result = new List<ITweet>();
context = context != null ? context : new TwitterContext(_auth);
// This is the example as given in the LinqToTwitter documentation, but the 'await' command doesn't work - I see an error 'The name 'await' does not exist in the current context' - errr...
var tweets = await (from tweet in context.Status
where tweet.Type == StatusType.User &&
tweet.ScreenName == author
select tweet).ToListAsync();
// This code is completely wrong - I'm not sure what to do here - In JS I'd be looking at a callback, but C# seems to just continue after from the examples I've looked at, however 'tweets' is no longer a list, it's a 'Task' so not much use to me here.
if (tweets != null)
{
foreach (var tweet in tweets)
{
if (!tweet.Retweeted)
{
result.Add(new Tweet
{
Author = tweet.ScreenName,
Text = tweet.Text
});
}
else
{
result.Add(new Tweet
{
Author = tweet.RetweetedStatus.User.ScreenNameResponse,
Text = tweet.RetweetedStatus.Text,
Retweet = true,
RetweetedBy = tweet.ScreenName
});
}
}
}
Any advice here would be most welcome. I've been hunting through google articles and example code for several hours and the examples are so far away from mine when I'm looking at translations that I can't see where to begin - I don't think it's helped by the weird 'await' error that I'm getting, so I'm concerned I'm barking up the wrong tree somewhere.
After much more reading I now have something more like this...
var tweets = (from tweet in context.Status
where tweet.Type == StatusType.User &&
tweet.ScreenName == author
select tweet).Take(4).ToListAsync();
tweets.Wait();
if (tweets != null)
{
foreach (var tweet in tweets.Result)
{
...
(above excerpted from the second code block) - This seems to work fine with a manual call to the Wait() method on the tweets task but still doesn't answer the question as to why the 'await' keyword doesn't work.
I eventually got to the bottom of this, although whether satisfactorily or not I'm unsure.
The workaround above was what I decided to go with in the end. I looked at making async work all the way through. The trick I was missing was, that in order to use await, the method containing the await call must itself be asynchronous.
This would have been fine if the method call I was making was in a controller, but it's not, it was from a partial. This would be a significant change.
To make matters more complex I fundamentally don't want the page to render before the data has returned as to do so creates some significant front end challenges due to the nature of the site design.
To summarise...
If you actually want it async then you need to return the data from a controller method. If you don't then I think my workaround above should work for you.