private void OpenInternal()
        {
            CompleteStatus status = CompleteStatus.Success;

            try
            {
                try
                {
                    isWaiting = true;
                    OnLoading(new EventArgs());
                }
                finally
                {
                    isWaiting = false;
                }
                if (canceled)
                {
                    return;
                }

                // 開く処理を行う
                if (modeOpen)
                {
                    Invoke(new MethodInvoker(Opening));
                }

                // キャッシュを読み込み表示
                ReadCache(resCollection);

                if (canceled)
                {
                    return;
                }

                Invoke(new MethodInvoker(WriteBegin));

                if (canceled)
                {
                    return;
                }

                if (modeOpen)
                {
                    Invoke(new WriteResMethodInvoker(Write), new object[] { resCollection });

                    // スクロール位置を復元 (値が0の場合は復元しない)
                    if (modeOpen && headerInfo.Position != 0.0f)
                    {
                        Invoke(new PositionMethodInvoker(SetScrollPosition),
                               new object[] { headerInfo.Position });
                    }
                }

Retry:
                try
                {
                    // サーバーに接続
                    if (OpenReader())
                    {
                        if (canceled)
                        {
                            return;
                        }

                        Reading();

                        // あぼーんを検知した場合
                        if (aboneDetected)
                        {
                        }
                    }
                    else
                    {
                        headerInfo.NewResCount = 0;
                        ThreadIndexer.Write(Cache, headerInfo);
                    }
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                }

                // 再試行が要求された場合、最初から
                if (retried)
                {
                    goto Retry;
                }

                if (canceled)
                {
                    return;
                }


                Invoke(new MethodInvoker(WriteEnd));
            }
            catch (Exception ex)
            {
                status = CompleteStatus.Error;
                //			isOpen = false; #10/15
                TwinDll.Output(ex);
                OnStatusTextChanged(ex.Message);
            }
            finally
            {
                // 中止された場合はETagをリセット
                if (canceled)
                {
                    headerInfo.ETag = String.Empty;
                }

                indicesValues.Clear();

                canceled = false;

                lock (syncObject)
                    thread = null;

                if (status == CompleteStatus.Success)
                {
                    OnStatusTextChanged(
                        String.Format("{0}の読み込みを完了 (新着: {1}件)",
                                      headerInfo.Subject, headerInfo.NewResCount));
                }
                /** 9/26 追加 **/
                else if (reader is X2chAuthenticateThreadReader)
                {
                    X2chRokkaResponseState rokkaState = ((X2chAuthenticateThreadReader)reader).RokkaResponseState;
                    if (rokkaState != X2chRokkaResponseState.Success)
                    {
                        TwinDll.Output("RokkaResponseState: {0}, URL: {1}, ", rokkaState, headerInfo.Url);
                    }
                    OnStatusTextChanged(String.Format("RokkaResponseState: {0}", rokkaState));
                }
                /****/

                IsReading             = false;
                lastCompletedDateTime = DateTime.Now;

                OnComplete(new CompleteEventArgs(status));
            }
        }
        /// <summary>
        /// データを読み込む&書き込む
        /// </summary>
        private void Reading()
        {
            ResSetCollection items = new ResSetCollection(),
                             buffer = new ResSetCollection();
            int read = -1, byteParsed, totalByteCount = 0;

            while (read != 0)
            {
                if (canceled)
                {
                    return;
                }

                read = reader.Read(buffer, out byteParsed);

                // あぼーんを検知した場合、処理を中止。
                if (read == -1)
                {
                    aboneDetected = true;
                    return;
                }

                totalByteCount += byteParsed;

                items.AddRange(buffer);

                // 逐次受信の場合はビューアに書き込む
                if (!isPackageReception)
                {
                    if (canceled)
                    {
                        return;
                    }

                    Invoke(new WriteResMethodInvoker(WriteInternal), new object[] { buffer });
                }
                buffer.Clear();

                OnReceive(new ReceiveEventArgs(
                              reader.Length, reader.Position, read));

                OnStatusTextChanged(
                    String.Format("{0} 受信中 ({1}/{2})",
                                  headerInfo.Subject, reader.Position, reader.Length));
            }

            // 一括受信の場合はここで一気にフラッシュ
            if (isPackageReception)
            {
                if (canceled)
                {
                    return;
                }

                Invoke(new WriteResMethodInvoker(WriteInternal), new object[] { items });
            }

            try
            {
                // スレッドのインデックス情報を保存
                storage            = new LocalThreadStorage(Cache, headerInfo, StorageMode.Write);
                storage.BufferSize = bufferSize;
                storage.Write(items);

                headerInfo.GotByteCount += totalByteCount;
                headerInfo.GotResCount  += items.Count;
                headerInfo.NewResCount   = items.Count;
                ThreadIndexer.Write(Cache, headerInfo);
            }
            catch (Exception ex)
            {
                TwinDll.Output(ex);
            }
            finally
            {
                storage.Close();
            }

            SaveThreadListIndices();
        }