public AccountScheduler(AccountInfo info) { this._accountInfo = info; this.AddSchedule(new HomeReceiveTask(info)); this.AddSchedule(new MentionReceiveTask(info)); this.AddSchedule(new DirectMessageReceiveTask(info)); this.AddSchedule(new SentDirectMessageReceiveTask(info)); this.AddSchedule(new FavoritesReceiveTask(info)); this.AddSchedule(new MyTweetsTask(info)); Task.Factory.StartNew(() => { try { // テストを飛ばす ApiHelper.ExecApi(() => info.Test()); } catch { } }); ThreadHelper.Halt += () => this.StopSchedule(); }
/// <summary> /// ストリーミングAPIへ接続します。<para /> /// 接続に失敗した場合、規定アルゴリズムに沿って自動で再接続を試みます。<para /> /// それでも失敗する場合はfalseを返します。この場合、再接続を試みてはいけません。 /// </summary> /// <param name="track">トラック対象キーワード</param> private void ConnectCore(AccountInfo info, string track) { try { int failureWaitSec = 0; while (true) { // 接続 try { using (var n = NotifyStorage.NotifyManually("@" + info.ScreenName + ": インターネットへの接続を確認しています...")) { while (!NetworkInterface.GetIsNetworkAvailable()) { info.ConnectionState = ConnectionState.WaitNetwork; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); // ネットワークが利用可能になるまでポーリング Thread.Sleep(10000); } } using (var n = NotifyStorage.NotifyManually("@" + info.ScreenName + ": 接続のテストをしています...")) { info.ConnectionState = ConnectionState.WaitTwitter; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); try { if (!ApiHelper.ExecApi(() => info.Test())) throw new Exception(); } catch { throw new WebException("Twitterが応答を停止しています。"); } } using (var n = NotifyStorage.NotifyManually("@" + info.ScreenName + ": 接続しています...")) { info.ConnectionState = ConnectionState.TryConnection; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); System.Diagnostics.Debug.WriteLine("User Streams Connection with Track: " + track); connection = streamingCore.ConnectNew( info, StreamingDescription.ForUserStreams(TwitterDefine.UserStreamsTimeout, track: track, repliesAll: info.AccountProperty.UserStreamsRepliesAll)); } } catch (WebException we) { if ((int)we.Status == 420) { // 多重接続されている throw new WebException("@" + info.ScreenName + ": 多重接続されています。接続できません。"); } if (we.Status == WebExceptionStatus.Timeout) // タイムアウト例外なら再試行する { NotifyStorage.Notify("@" + info.ScreenName + ": User Streams接続がタイムアウトしました。再試行します..."); } else { string descText = we.Status.ToString(); if (we.Status == WebExceptionStatus.UnknownError) { descText = we.Message; } if (we.Status == WebExceptionStatus.ProtocolError) { var hwr = we.Response as HttpWebResponse; if (hwr != null) { descText += " - " + hwr.StatusCode + " : " + hwr.StatusDescription; } } throw new WebException("接続に失敗しました。(" + descText + ")"); } } catch { throw; } if (connection != null) { // Connection successful info.ConnectionState = ConnectionState.Connected; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); return; } if (failureWaitSec > 0) { if (failureWaitSec > Setting.Instance.ConnectionProperty.UserStreamsConnectionFailedMaxWaitSec) { throw new WebException("User Streamsへの接続に失敗しました。"); } else { NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続に失敗。再試行まで" + failureWaitSec.ToString() + "秒待機...", failureWaitSec / 1000); // ウェイトカウント Thread.Sleep(failureWaitSec * 1000); NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続を再試行します..."); } } else { NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続に失敗しました。再試行します..."); } // 最初に失敗したらすぐに再接続 // 2回目以降はその倍に増やしていく // 300を超えたら接続失敗で戻る if (failureWaitSec == 0) { failureWaitSec = Setting.Instance.ConnectionProperty.UserStreamsConnectionFailedInitialWaitSec; } else { failureWaitSec *= 2; } } } catch (ThreadAbortException) { throw; } catch (Exception e) { this.AccountInfo.ConnectionState = ConnectionState.Disconnected; ConnectionManager.OnConnectionStateChanged(EventArgs.Empty); throw new WebException("User Streamsへの接続に失敗しました。", e); } }