This has me a bit baffled. I've got some code that is basically polling Twitter once every 60 seconds to parse any updates to my timeline. There's a bunch of business logic on top because it runs via a task scheduling engine, but it comes down to a relatively simple GET to https://api.twitter.com/1.1/statuses/user_timeline.json.
Every 12 hours, at exactly 1004 and 2204 GMT I get the following exception logged:
The important bit is at the bottom:
The request was aborted: Could not create SSL/TLS secure channel.
I think there are a few places from which the problem could stem:
Here's the code (C#) that's making the call to Twitter:
That's part of a library I've published for interacting with social media services (see http://niknaksocial.codeplex.com/). I'm aware of the fact it's running an async method and then just waiting for it, let's ignore that misdemeanor for now
The task scheduling code is also published (see http://niknakservices.codeplex.com/) but I'm fairly confident it's ok since it's quite widely used and tested on other things.
But I'm open to suggestions on what this might be. Has anyone seen anything similar? The closest I've found to the problem is mentioned here. I've not done any network tracing but that's something to try.
Answers on a postcard...?
Every 12 hours, at exactly 1004 and 2204 GMT I get the following exception logged:
Code:
Exception type: System.AggregateException
Exception message: One or more errors occurred.
Exception stack trace:
at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout)
at System.Threading.Tasks.Task.WaitAll(Task[] tasks)
at Niknak.Social.Twitter.UserTimeline`1.GetTweets[Tweet,User,Media,MediaSize](String screenName, Int32 count, Boolean includeRTs, String sinceMessageId)
at NiknakV3.Business.Services.TaskScheduler.Processors.TwitterFeed.ProcessTask(SimpleTaskConfig`1 config, AuditLog currentLog, Boolean& terminate)
Inner exception message: One or more errors occurred.
Inner exception stack trace:
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at Niknak.Social.Twitter.UserTimeline`1.<>c__DisplayClass3`4.<GetTweets>b__0(Task`1 requestTask)
at System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
Inner exception message: An error occurred while sending the request.
Inner exception stack trace:
Inner exception message: The request was aborted: Could not create SSL/TLS secure channel.
Inner exception stack trace:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
The important bit is at the bottom:
The request was aborted: Could not create SSL/TLS secure channel.
I think there are a few places from which the problem could stem:
- Twitter API itself
- Method calling Twitter
- Task scheduling logic - some kind of disposal bug perhaps
- The server/OS/networking on which the Windows Service is running
Here's the code (C#) that's making the call to Twitter:
Code:
public static List<Tweet> GetTweets<Tweet, User, Media, MediaSize>(string screenName, int count, bool includeRTs, string sinceMessageId)
where Tweet : IMessage, new()
where User : IUser, new()
where Media : IMedia, new()
where MediaSize : IMediaSize, new()
{
if (string.IsNullOrEmpty(screenName))
throw new ArgumentNullException("screenName");
if (count <= 0)
throw new ArgumentNullException("count");
if (string.IsNullOrEmpty(sinceMessageId) || sinceMessageId == "0")
throw new ArgumentNullException("sinceMessageId");
List<Tweet> outList = new List<Tweet>();
List<JsonObject> tweets = new List<JsonObject>();
using (HttpClient client = new HttpClient(new OAuthMessageHandler<OAuthSettings>(new HttpClientHandler())))
{
if (client == null)
throw new Exception("Unable to initiate HttpClient object");
string requestUrl = string.Format(
APITIMELINEURL,
screenName,
count,
includeRTs.ToString().ToLower(),
sinceMessageId
);
Task retrieveTweets = client.GetAsync(requestUrl).ContinueWith(requestTask =>
{
//get HTTP response from completed task
HttpResponseMessage response = requestTask.Result;
//check that response was successful or throw exception
response.EnsureSuccessStatusCode();
//necessary when retrieving more than about 15 tweets at a time
MediaTypeFormatter.SkipStreamLimitChecks = true;
//read response asynchronously as JsonValue and dump into list for further processing
Task processTweets = response.Content.ReadAsAsync<JsonArray>().ContinueWith(readTask =>
{
JsonArray statuses = readTask.Result;
foreach (JsonObject status in statuses)
tweets.Add(status);
});
Task.WaitAll(processTweets);
});
Task.WaitAll(retrieveTweets);
}
if (tweets != null)
foreach (JsonObject tweet in tweets)
{
//we need to do some checks on the message retrieved to ensure it's not fubar
if (!Utils.IsValidTweetJson(tweet))
continue;
outList.Add(Utils.ParseTweetJson<Tweet, User, Media, MediaSize>(tweet));
}
return outList;
}
That's part of a library I've published for interacting with social media services (see http://niknaksocial.codeplex.com/). I'm aware of the fact it's running an async method and then just waiting for it, let's ignore that misdemeanor for now

The task scheduling code is also published (see http://niknakservices.codeplex.com/) but I'm fairly confident it's ok since it's quite widely used and tested on other things.
But I'm open to suggestions on what this might be. Has anyone seen anything similar? The closest I've found to the problem is mentioned here. I've not done any network tracing but that's something to try.
Answers on a postcard...?
