タイムアウト、プールサイズの制限値

VB2010で業務アプリケーションの集計ツールを作成しています。
仕組みは単純で、下記の様にDateTimePicker(カレンダー)から日付を選び
ボタンクリックでフォーム内のデータグリッド内に集計値が入っていく仕組みです。

'カレンダー日付選択
Sub Aggregate()
'日付の取得
DateTimePicker1.Format = DateTimePickerFormat.Custom
DateTimePicker1.CustomFormat = "yyyy-MM-dd

1つのフォームにデータグリッドが10個ほどあるので画面遷移までに5秒くらいかかってしまいます。
1度目の表示は問題ないのですが、日付を選択し直し2度、3度と実行すると
”タイムアウトに達しました。プールから接続を制限する前にタイムアウト期間が過ぎました。
プールされた接続がすべて使用中で、プールサイズの制限値に達した可能性があります。”
と表示されてしまいます。開放も行っているつもりで原因がわかりません。
原因がわかれば教えていただきたいです。処理をスピードアップできる方法があればそれもお願いします。
接続文字は以下の通りです。

Function CONNECT(ByVal SqlText As String) As String
Dim St As String
Dim Cn As New System.Data.SqlClient.SqlConnection
Dim SQL As New System.Data.SqlClient.SqlCommand
Dim ServerName As String = "AAAAAAAAA"
Dim UserID As String = "BBBBBBBBB"
Dim Password As String = "CCCCCCC"
Dim DatabaseName As String = "DB"
Dim Adapter As New System.Data.SqlClient.SqlDataAdapter
Dim Table As New DataTable

Adapter.SelectCommand = SQL
SQL.Connection = Cn
SQL.CommandTimeout = 120
St = "Server=" & ServerName & ";"
St &= "User ID=" & UserID & ";"
St &= "Password=" & Password & ";"
St &= "Initial Catalog=" & DatabaseName
Cn.ConnectionString = St
SQL.CommandText = SqlText
Cn.Open()
Return SQL.ExecuteScalar
SQL.Connection = Nothing
SQL.Transaction = Nothing
SQL.Dispose()
Cn = Nothing
Cn.Dispose()
Cn.Close()
End Function

データグリッドの転記は下記の様なコードをずらっと書いています。
DataGridView10(2, 3).Value = CONNECT("SELECT COUNT(*)" & _
" FROM dbo.IOTBL, dbo.APLTBL" & _
" WHERE APLTBL.APLID=IOTBL.APLID" & _
" And (APLTBL.APLTYPE='JA01')" & _
" And (APLTBL.DELETED<>'1')" )

このQ&Aに関連する最新のQ&A

A 回答 (3件)

Return以後のコードは実行されませんよ。


このコードだと,作成したSqlConnectionがGCされるまで開きっぱなしになります。
その結果,接続数が増えすぎてエラーになっているのだと思います。

SqlConnectionとSqlCommandを作る時に,Usingブロックを使ってみてください。
これにより,正しくDisposeが呼び出され,接続が閉じられるようになります。

e.g.)
Using cn = New SqlConnection()
Using cm = New SqlCommand()
' ....
End Using
End Using
これは,
Dim cn As SqlConnection = Nothing
Try
cn = New SqlConnection()
Dim cm As SqlCommand = Nothing
Try
cm = New SqlCommand
' ...
Finally
If cm IsNot Nothing Then DirectCast(cm, IDisposable).Dispose()
End Try
Finally
If cn IsNot Nothing Then DirectCast(cn, IDisposable).Dispsoe()
End Try
とほぼ等価で,Usingブロックを出たタイミングでDisposeを呼び出してくれます。
# VB2005からの機能です。

この回答への補足

ありがとうございます。
Using Cnは具体的にこのコードの場合どこに入れればよいのでしょうか?

補足日時:2011/04/20 13:05
    • good
    • 0

ANo.2です。



元のコードから無駄をそぎ落としつつUsingを使うなら,

Function CONNECT(ByVal SqlText As String) As String
Dim Builder = New SqlConnectionStringBuilder()
Builder.DataSource = "AAAAAAAAA"
Builder.UserID = "BBBBBBBBB"
Builder.Password = "CCCCCCC"
Builder.InitialCatalog = "DB"

Using Cn = New SqlConnection(Builder.ConnectionString)
Using SQL = New SqlCommand(SqlText, Cn)
Cn.Open()
Return TryCast(SQL.ExecuteScalar(), String)
End Using
End Using
End Function

という感じになると思います。

UsingブロックはVisual Basicにおけるリソース管理の基礎でもあるので,
ちゃんと調べておいた方がよいと思います。
    • good
    • 0

はじめまして通るすがるともうします。

わたしははっきりいってADOは使ったことはないのですが(環境もないし)、基本的にDBの使用法として(1)でopn (2)sql発行 (3)close(Disconect)の手順で行うとおもうのですが、上記ソースの部分で以下の疑問があります。
 
0.上のソース 
1. Cn.Open()           <-dbへの接続
2.Return SQL.ExecuteScalar  <-sql発行
3.SQL.Connection = Nothing
4.SQL.Transaction = Nothing
5.SQL.Dispose()
6.Cn = Nothing
7.Cn.Dispose()
8.Cn.Close()            <- ここでクローズ?? (dbのdisconect?)
だとすると、8行目のまえに5行目から6行目ででインスタンス解放初期化していては8行目で何をクローズすればいいのか判断できないと思います(多分ここでタイムアウト?)。なので8行目は2行目の直下に書くべきでは?
あと、このソースの部分は同じ接続内容で連続して呼ばれるわけですよね?
だとするとわざわざ初期化(5行目から7行目)する必要ってあるのでしょうか?たとえ使用しなくなってもせっかくメモリに常駐されたのなら次に接続を要求したときにすでにメモリに常駐したところを使用しにいくと思うので記述しないほうが早く動作すると思います。もし、確実にメモリを解放し解放したところを確実に使用できるようにしたければ8行目の後に、ガベージコレクションを起動しなければならないと思います。(System.GC.Collect)。<例をあげるのならたとえば、EXCELを一度目立ち上げると2回目に立ち上げたときは1回目より高速い起動されますね!>なので記述しているソースは少し矛盾しているかと思います。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qタイムアウトする仕組みを作りたい

VB2008でWebにアクセスしています。

アクセス時に次の関数を呼び出して、表示が完了するまで待機しています。

Private Function WebWait(ByVal time As Integer)
 Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
  Application.DoEvents()
 Loop
End Function

ただ、サイトが応答しなくてずっと待ったままになる場合があります。
10秒応答がなかった場合に処理を中断させたいのですが、方法が判りません。

PHPならば、タイムスタンプをスタート時間と比較して、終了判断させることができます。
こんな感じを考えています。

Private Function WebWait(ByVal time As Integer)
 スタート時間を格納
 Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
  Application.DoEvents()
  スタート時間と比較して、タイムアウトならLoopを抜ける
 Loop
End Function


しかし、VB2008で同様の関数を見つけることができませんでした。
dateandtimeで似たものはありますが、ずっとカウントアップするものではありませんでした。

適切な関数、もしくは方法がありましたら、教えてください。

よろしくお願いします。

VB2008でWebにアクセスしています。

アクセス時に次の関数を呼び出して、表示が完了するまで待機しています。

Private Function WebWait(ByVal time As Integer)
 Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
  Application.DoEvents()
 Loop
End Function

ただ、サイトが応答しなくてずっと待ったままになる場合があります。
10秒応答がなかった場合に処理を中断させたいのですが、方法が判りません。

PHPならば、タイムスタンプをスタート時間と比較して、終了判断...続きを読む

Aベストアンサー

タイマーコントロールを使ってはいかがですか?

タイムアウト用のフラグ変数を用意
dim m_bTimeOut as boolean

Private Function WebWait(ByVal time As Integer)
  ' タイマーの初期化
  Timer1.Enabled = false
  ' ms単位なので 10*1000 を代入
  Timer1.Interval = 10 * 1000
  ' フラグを初期化
  m_bTimeOut = false
  Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
  Application.DoEvents()
  if m_bTimeOut = true then
    Timer1.Enabled = false
    MsgBox "タイムアウトしました"
  end if
 Loop
 Timer1.Enabled = false
End Function

' タイマーイベント
Private Sub Timer1_Tick(引数省略)
  m_bTimeOut = true
  Timer1.Enabled = false
End Sub
といった具合で ・・・

タイマーコントロールを使ってはいかがですか?

タイムアウト用のフラグ変数を用意
dim m_bTimeOut as boolean

Private Function WebWait(ByVal time As Integer)
  ' タイマーの初期化
  Timer1.Enabled = false
  ' ms単位なので 10*1000 を代入
  Timer1.Interval = 10 * 1000
  ' フラグを初期化
  m_bTimeOut = false
  Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
  Application.DoEvents()
  if m_bTimeOut = true then
    Timer1.Enabled...続きを読む

QVB.netで、シリアル通信のタイムアウト処理について

VB.netで、シリアル通信のタイムアウト処理について

http://msdn.microsoft.com/ja-jp/library/7ya7y41k.aspx
このサイトのコードを、参考にしています。
------------------------------------ここから
Dim com1 As IO.Ports.SerialPort = Nothing
Try
com1 = My.Computer.Ports.OpenSerialPort("COM1")
com1.ReadTimeout = 10000

Catch ex As TimeoutException
returnStr = "Error: Serial Port read timed out."
Finally
If com1 IsNot Nothing Then com1.Close()
End Try

------------------------------------ここまで

この方法ですと、タイムアウトが発生したらポートを閉じるようですが、これを、送信したシリアルのデータを再度、送信させたいと思います。
そして、何度かリトライを掛けた後に、やっぱり駄目だったときに
ポートを閉じたいと思います。

どんな方法がありますか?

参考になりそうなサイトなどがありましたら、教えていただけませんか。
以上、よろしくお願いします。

VB.netで、シリアル通信のタイムアウト処理について

http://msdn.microsoft.com/ja-jp/library/7ya7y41k.aspx
このサイトのコードを、参考にしています。
------------------------------------ここから
Dim com1 As IO.Ports.SerialPort = Nothing
Try
com1 = My.Computer.Ports.OpenSerialPort("COM1")
com1.ReadTimeout = 10000

Catch ex As TimeoutException
returnStr = "Error: Serial Port read timed out."
Finally
If com1 IsNot Nothing Then com1.Close()
End Try

----------------...続きを読む

Aベストアンサー

タイムアウトはWrite/Read(送受信)系メソッドで
発生します。そのメソッドをTry~Catchブロックで
ハンドリングしないと意味ないでしょ。
掲題のプログラムはポートを開いて、タイムアウトの
時間を設定しただけですから、送受信していません。

QEXCEL VBAで計算値を四捨五入、切り上げ、切捨てする方法

ネットで探してみたのですが、計算結果を四捨五入して特定のセルを
返すにはどうしたらいいのでしょうか?

Sub hokangosa()

Dim ZPS As Double
Dim ZPOS As Double
Dim DMN As Double
MsgBox (" >>> 補間誤差自動計算 <<< ")
MsgBox (" >>> 初期値入力します <<< ")
ZPS = InputBox(">>> ステップを入力してください<<<")
ZPOS = Sheet1.Cells(22, 4).Value
DMN = ZPOS / ZPS
Sheet1.Cells(23, 6).Value = DMN
End Sub

ここでDMNの値を四捨五入したいです。

またこれとは別に切上げ、切捨ても教えていただけるとありがたいです。

Aベストアンサー

DMN = Application.WorksheetFunction.Round(ZPOS / ZPS, 0)
で、四捨五入
DMN = Application.RoundDown(ZPOS / ZPS, 0)
で切り捨て
DMN = Application.RoundUp(ZPOS / ZPS, 0)
で切り上げです。

引数で、対象桁を変更できます。

Q別のDBからテーブルをコピーする方法

SQL Server2005 Express Edition を使っています。
異なるDB間(同じコンピュータ内)で、テーブルをコピーしたいの
ですが・・・
コピー元DB名:DB_A
コピー元テーブル名:dbo.顧客
コピー先DB名:DB_B

テーブルのコピーは select * into ・・・ from ・・・ を使えばできそうですが、別DBの場合の方法がわかりません。
お教えいただければ幸いです。
よろしくお願いいたします。

Aベストアンサー

別のDBでも同じインスタンス内ならば同じです。

SELECT * INTO DB_B.dbo.顧客 FROM DB_A.dbo.顧客

Q英語で「個数」「件数」は?

質問は単純です。
英語で「個数」や「件数」をなんというか、です。

とりあえず、思いついたのは、numberでした。
たとえば、「りんごの個数」は"a number of apples"ですか?
でも、"a number of"は「いくつかの」という意味ですよね。

「データの件数」は"a number of data"でしょうか?

私は英語はほとんど出来ませんが、numberは「個数」というよりも「番号」という意味であるような気がしてなりません。

Aベストアンサー

>「個数」や「件数」をなんというか、です。
>とりあえず、思いついたのは、numberでした。
意外に思われるかもしれまんせんが、語の選択はnumberであっています、と思います。

>「りんごの個数」
the number of (the) apples

>「データの件数」
the number of (the) data

>numberは「個数」というよりも「番号」という意味であるような気がしてなりません。
実は、昔、私も、「個数や件数はなんていうのかな、え、number? え、本当?」と、奇異に感じたことを、思い出しました。

QSQL Server時間切れについて

初めまして。SQL初心者です。
あるシステムにおいて、SQLサーバが無応答?になり、システムがダウンしてしまい、困っています。

Windows2000Server、SQL Server2000、VB6を用いてDBに定期的にRead&Write、及び各種のデータ表示を行っています。
ADOを使用して、接続や各コマンドを実行しているのですが、ごくたまに以下のエラーが出てしまいます。
Code:-2147217871,Description:時間切れになりました。Source:Microsoft OLE DB Provider for SQL Server,SQL State:HYT00,NativeError:0
過去ログや他サイトを調べた結果、コネクションのCommandTimeoutの秒数を延長させる、とあったので60秒に変更しました。
が、不定期(大体1週間~10日前後で夜中や朝方などにもあり)にこのエラーが出てしまい、約1時間~1時間半もダウンしています(この間のエラーをOn Errorではじいてログファイルに保存しています)。
毎分必ず実行しているストアド(20装置分のデータをUPDATEするので1分に20回実行する)があるのですが、必ずと言っていいほどこのストアド実行中に落ちています。
このストアドに5~6個のパラメータを渡し、複数のテーブルに対してUPDATE処理を行っています。
正常に動作している時は、数日間全く問題無いので、ストアドやVBのコードに間違いは無いと思います。

そこで、SQL Serverの設定等を見直したところ、1つ気になったところが。データベースファイル
\Microsoft SQL Server\MSSQL\Data\aaa.MDF
のサイズが14Gになっていました・・・。
このファイルにアクセスする時にSQL Serverで高負荷になってしまい、無応答のような状態になってしまうのでは?と思っていますがどうでしょう?

不定期に発生し、かつ再現性が無く、原因が掴めずに本当に困っています。
先輩方、何でも良いのでアドバイスをお願い致します。

初めまして。SQL初心者です。
あるシステムにおいて、SQLサーバが無応答?になり、システムがダウンしてしまい、困っています。

Windows2000Server、SQL Server2000、VB6を用いてDBに定期的にRead&Write、及び各種のデータ表示を行っています。
ADOを使用して、接続や各コマンドを実行しているのですが、ごくたまに以下のエラーが出てしまいます。
Code:-2147217871,Description:時間切れになりました。Source:Microsoft OLE DB Provider for SQL Server,SQL State:HYT00,NativeError:0
過去ログや他サイ...続きを読む

Aベストアンサー

14Gですか・・・大きいですね。
データの構造がどうなのか解らないので、
容量的に妥当かどうかはわかりませんが、
一度インデックスの再構築と圧縮を掛けてはどうでしょうか


CREATE PROCEDURE SP_COMPRESS AS

DECLARE @name varchar(30)

DECLARE tnames_cursor CURSOR FOR
SELECT name FROM sysobjects
WHERE type = 'U'
OPEN tnames_cursor

FETCH NEXT FROM tnames_cursor INTO @name
WHILE (@@fetch_status <> -1)
BEGIN
PRINT @name + 'のDBREINDEX...'
EXEC ('DBCC DBREINDEX ('+ @name + ')' )
FETCH NEXT FROM tnames_cursor INTO @name
END
DEALLOCATE tnames_cursor

dbcc SHRINKFILE("SampleDb_Log",1)
DBCC SHRINKDATABASE("SampleDb",1)
GO


データベース名は自分の環境に合わせてください。
また、バックアップは必ず取っておいてください。
14Gもあれば結構時間がかかると思いますが・・・

とりあえず参考程度に・・・

14Gですか・・・大きいですね。
データの構造がどうなのか解らないので、
容量的に妥当かどうかはわかりませんが、
一度インデックスの再構築と圧縮を掛けてはどうでしょうか


CREATE PROCEDURE SP_COMPRESS AS

DECLARE @name varchar(30)

DECLARE tnames_cursor CURSOR FOR
SELECT name FROM sysobjects
WHERE type = 'U'
OPEN tnames_cursor

FETCH NEXT FROM tnames_cursor INTO @name
WHILE (@@fetch_status <> -1)
BEGIN
PRINT @name + 'のDBREINDEX...'
EXEC ('DBCC DBREINDEX (...続きを読む

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

Qvb.netで画面のコントロールId名を変数で動的に制御し処理する方法

以下のような処理がしたいです。
実現方法をご存知でしたらご教授下さい。

画面のコントロールText1~Text3があります。
For~Nextでこのコントロールに値をセットしたいです。

For i = 1 To 3
  Texti.Text = i
  ※このiのTextの後ろのiの部分を1~3と動的に変更し、各Textに値を設定したいです。
Next

Aベストアンサー

こんにちは、webでは、findcontrolを使うみたいです。

いかに、参考URLから、引用すると
***********************************
Dim L, U, i As Integer
Dim tx As System.Web.UI.WebControls.TextBox
L = LBound(dat)
U = UBound(dat)
For i = L To U
'コントロール名を探し出す
tx = FindControl("TextBox" & CStr(i))
'見つかったコントロールのTextプロパティに代入
tx.Text = dat(i)
Next

******************引用終わり*******
このようにすると良いみたいです。
asp findcontrolで、検索すると、
結構ヒットするみたいです。

参考URL:http://natchan-develop.seesaa.net/

QDataTableから条件を満たした行を別のDatatableへコピーしたい

VC#2005とSQLServer2005ExpressEditionでWindowsアプリケーションを作成しています。

データベースの中から1つのマスタテーブルのデータを呼び出すのにTableAdapterを使ってDataTableにデータをバインドしました。
そこから条件を満たしている行をすべて抽出して同じ型のDataTableにデータをコピーしたいのです。

ですから、DataTableは2つ用意しています。1つは上記の通りデータをバインドしていますが、もう1つは宣言しただけなのでまだ空っぽの状態です。
DataTableにはカラムが3列あり、その中の1列をグループIDとしています。
条件としてはグループIDが同じであるということです。
やりたいことは条件を満たしている行をすべて抽出して空のデータテーブルにコピーすることです。

どなたかご存知の方いらっしゃれば教えてください。
よろしくお願いします。

Aベストアンサー

C#だったんですね … さほど変わりないと思いますが

お使いのコードが提示されていないのでこちらで適当な変数をでっち上げております
現在お使いのコードを支障の無い範囲で提示しましょう

//元のデータテーブルがdtSourceとすると
// テーブル構造をコピー
DataTable dt = dtSource.Clone();
DataRow r = null;
foreach( DataRow dtRow in dtSource.Select("選択するための文字列"))
{
  r = dt.NewRow();
  for( int n = 0; n < dtRow.ItemArray.Length; n++ )
  {
    r[n] = dtRow[n];
  }
  dt.Rows.Add( r );
}
といった具合になると思います

# 前回の投稿中のstSorceはdtSourceの単なるミスです

Qバッチファイルを利用したフォルダの一括削除

バッチファイルを利用して特定のフォルダ内にあるすべての
ファイル&フォルダを削除したいと思っています。

Dドライブ直下のファイルを削除するときは
del "D:\*.*"
これですべてのファイルは削除できるかと思います。

Dドライブ直下にフォルダがあった場合どのように削除したらよいのでしょうか?
rmdirコマンドでは、フォルダごとに指定してやる必要がありますよね?
ワイルドカードを使用してフォルダを削除する方法などあるのでしょうか?

特定フォルダそのものを削除してしまって、作り直したほうが早いかとも
思いましたが、アクセス権設定を再度しなければならなくなるので
何か良い方法はないでしょうか?

ご存知の方いらっしゃいましたら、よろしくお願いいたします。

Aベストアンサー

こんにちは。
せっかくのバッチなので1つのコマンドでやろうと思わないで、
二段階に分ける方法はいかがでしょう。

1.配下のファイルを削除する
2.配下のサブフォルダを削除する。


pushd D:\test
del *.*
for /D %%f in ( * ) do rmdir /s "%%f"


確認せずにやるなら /q オプションで。

pushd D:\test
del /q *.*
for /D %%f in ( * ) do rmdir /s /q "%%f"


人気Q&Aランキング

おすすめ情報