■56556 / inTopicNo.12) |
Re[2]: ODPを介したSQLコマンドのキャンセルについて |
□投稿者/ hanayama (7回)-(2011/01/19(Wed) 13:24:46)
|
■No56551 (todo さん) に返信
>>フォーム上のボタンを押下可能にしなければならないため、
>>クエリを別スレッドで発行しようと考えていますが、
>>そもそも、SQLコマンドの発行後の中止が出来るのかどうか
>>色々と情報をあさってはいますが、答えにたどり着けないでいます。
>
> SqlCommand.Cancel メソッド
> http://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlcommand.cancel(v=vs.71).aspx
>
> に別スレッドでExecuteReaderとCancelを行うサンプルがあります。
> SqlServer相手に試したところ SqlDataReader.Readで
> 「ユーザーによって操作がキャンセルされました。」
> という例外になりました。
> ODPに書き換えて試してみては?
ご回答ありがとうございます。
ご提示頂いた、ページのサンプルをODP用(.NET 1.1)に変えて確認しました。
何度か試しましたが(キャンセル時のSleepの時間変更や発行するSQL文を変え)
「ユーザーによって操作がキャンセルされました。」の例外は発生せず、
「キャンセルされた」ことが確認できませんでした。
処理上は、コマンド用スレッドの「Do While r.Read」中に、
キャンセル用スレッドの「_cmd.Cancel()」が呼び出されているのですが。
※ちなみにOracleCommand用の同メソッドの下記ページのサンプルでは
とてもコマンドがキャンセルされる気がしないです・・・
http://msdn.microsoft.com/ja-jp/library/system.data.oracleclient.oraclecommand.cancel%28v=vs.71%29.aspx
念のためODP用に変えたソースを載させて頂きます。
コンソールアプリケーションのMainメソッド(MTAThread)から、
下記ソースの「CancelTest()」を呼び出して確認しています。
------------------------------------------------------------------------
Private _cmd As OracleCommand
Private _e1 As AutoResetEvent = New AutoResetEvent(False)
Private _e2 As AutoResetEvent = New AutoResetEvent(False)
Public Sub IssueQuery()
Dim r As OracleDataReader
Dim rows As Integer = 0
Try
r = _cmd.ExecuteReader()
Do
Do While r.Read
rows = rows + 1
Loop
Loop While r.NextResult()
Console.WriteLine("FAILED: execution should not have finished, {0} rows read!", rows)
Catch
Console.WriteLine("PASSED: Got expected exception!")
End Try
_e1.Set()
End Sub
Public Sub CancelQuery()
System.Threading.Thread.Sleep(100)
_cmd.Cancel()
_e2.Set()
End Sub
Public Sub CancelTest()
Dim conn As OracleConnection = New OracleConnection("接続文字列")
conn.Open()
_cmd = New OracleCommand("", conn)
Dim evs() As AutoResetEvent = {_e1, _e2}
Dim t1Start As ThreadStart = New ThreadStart(AddressOf IssueQuery)
Dim t2Start As ThreadStart = New ThreadStart(AddressOf CancelQuery)
Dim t1 As Thread = New Thread(t1Start)
Dim t2 As Thread = New Thread(t2Start)
' cancel operation while results are coming back
_cmd.CommandText = "SELECT文"(結果セット取得まで約1分)
t1.Start()
t2.Start()
WaitHandle.WaitAll(evs)
conn.Close()
End Sub
------------------------------------------------------------------------
|
|