- - PR -
Shared変数について
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2003-10-11 01:48
いつもお世話になっております。
開発環境:ASP.NET(.NET Framework SDK v1.1)エディタで開発(VB) Shared(共有)変数について質問です。 DataGridのソート、ページング時に再びSQLを実行してデータをバインドさせて いるのですが、SQLの実行に時間がかかるためページロード時に実行した取得した データセットを同一画面内で共有させたいのですが、ページロード時にクリアされてしま います。 Shared(共有)変数を使えば実現できるような事がわかったのですがポストバック後に Shared(共有)変数を参照するとエラーになってしまいます。 何か書き方がわるいのでしょうか? そもそもデータセットにはShared(共有)変数は使えないのでしょうか? セッション変数を素直に使った方がよろしいのでしょうか? ご教授ください 仮に別のShared(共有)変数を文字列(String)で定義してみたところ正常に共有されています。 定義している個所のソースです。 Shared datSearch As DataSet | ||||
|
投稿日時: 2003-10-12 15:07
こんにちは。
そういうところも、WebアプリケーションでWindowsアプリケーションのような作りをすることを勧めないところです。 他のレスで他の方が書かれていますが(なので、ASP.NET系のスレッドは一通り目を通すことをお勧めします)、Webでは1つのGETなりPOSTなりのリクエストを処理すると、オブジェクトは破棄されます。つまり、HTTPは状態管理をしないのです。他の、Sharedな変数に入れた値は、そのオブジェクトを呼び出したリクエストが処理されると、破棄されます。破棄されるから、セッションが考え出され、セッション変数が用意されています。 | ||||
|
投稿日時: 2003-10-12 20:28
うーん、例えばサーバを分散しているとか、ASP.NETのプロセスを並列動作させている場合など、Shared変数が共有されないという状況はありえるのですが、そうでない場合は共有されているはずですが… # 再リクエスト前に再起動でもされていれば別ですが… # もしかして私が何か間違えている可能性もありますけど。 ただし、複数のユーザのリクエストでも共有されるとか、そういう問題は十分にありますので、こういった用途ではセッションとか使う方が良いというのは同意します。 元の質問者の現象についてはよく分かりませんです。 | ||||
|
投稿日時: 2003-10-13 00:19
SharedはWebアプリケーション全体で共有されます。
この意味が十分に理解できていて利用するならよいと思いますが、 基本的にはSessionオブジェクトやApplicationオブジェクトを 利用するべきでしょうね。 わざわざWebアプリケーション用に用意されているオブジェクト なんですし。 | ||||
|
投稿日時: 2003-10-14 08:39
そうでしょうか?結局、dllとして、aspnetの実行形式にロードされていますよね。とすると、アンロードされたらなくなるのでは? また、DataSetということなので、これはnewしなければなりません。文字列、Stringであれば、 Shared SharedString As String = "abc" とすれば、"abc"はメモリ上に確保され、その参照がSharedStringに入ります。参照が共有されても、"abc"というメモリはクラスが参照されたときに特定されるので、参照できます。しかし、DataSetでは、このような初期化はできません。参照することを共有できても、参照先を共有できない、と思うのですが。。。それとも、いったん入ると、アプリケーション、つまりワーカプロセスが動いている間中、ずっと解放されずに残る?それって、使いようによってはとても危険じゃないですか? なんにしても、発生するエラーがわからなければ、どういう現象なのかもわかりませんが。 | ||||
|
投稿日時: 2003-10-14 09:21
実験しました。
Public Shared SharedDataSet As DataSet Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load If IsPostBack Then DataGrid2.DataSource = SharedDataSet DataGrid2.DataBind() Else SharedDataSet = New DataSet("SHARED") Dim tbl As DataTable = SharedDataSet.Tables.Add() tbl.TableName = "SHARED TABLE" tbl.Columns.Add("COLUMN_A").DataType = GetType(String) Dim row As DataRow = tbl.NewRow row(0) = "ABC" tbl.Rows.Add(row) DataGrid1.DataSource = SharedDataSet DataGrid1.DataBind() End If End Sub ページにはDataGrid1と、DataGrid2、およびポストバックを発生させるためにボタンを置きました。ページを表示すると、DataGrid1にデータが表示され、ボタンクリックでDataGrid2にデータが表示されます。 {投稿日時: 2003-10-12 15:07}でいったように、オブジェクトが破棄されているなら、DataGrid2にはでないはずなので、先のようではない、ということです。 ということで、やはり「どんなエラーが発生して、どんなメッセージが表示されたのか」教えてください。 #WebForm2にredirectして、そちらから参照もOk | ||||
|
投稿日時: 2003-10-14 10:11
> そうでしょうか?結局、dllとして、aspnetの実行形式にロードされていますよね。とすると、アンロードされたらなくなるのでは?
DLL(アセンブリ)って、単体でアンロードされることってありましたっけ? アプリケーションドメイン単位でしか出来ないと思ってたんですが。 # ASP.NET特有の動作で何かあるなら、私が勘違いしてるかもしれません。 というか、特に事情がなければアンロードは起こらないと思うんですが… もちろん、一定期間ごとの再起動とかで、いつの間にか再度初期状態に戻ることはありますので、このような場合に正常に動作しないようなことはやめたほうがいいでしょうけど… > また、DataSetということなので、これはnewしなければなりません。文字列、Stringであれば、 > Shared SharedString As String = "abc" > とすれば、"abc"はメモリ上に確保され、その参照がSharedStringに入ります。参照が共有されても、"abc"というメモリはクラスが参照されたときに特定されるので、参照できます。しかし、DataSetでは、このような初期化はできません。参照することを共有できても、参照先を共有できない、と思うのですが。。。 初期化というか、DataSetの作成については、最初に行っているという前提で考えてましたが… しかし、最初の質問を読み返してみると、この初期化あたりというか、最初の動作がちょっと怪しいように思えてきました。確かに、きちんと初期化を行っていないような気がしますね… > それとも、いったん入ると、アプリケーション、つまりワーカプロセスが動いている間中、ずっと解放されずに残る?それって、使いようによってはとても危険じゃないですか? むしろ勝手に解放されたらびっくりしたり… はい、使いようによってはとても危険です。 | ||||
|
投稿日時: 2003-10-14 11:41
たくさんの返答ありがとうございました。
Shared変数うまくいきました。ありがとうございました。 detasetを取得してShared変数に格納した後にdetasetを開放してしまっている ため2回目以降にデータが表示されないという単純な理由でした。 最初に取得したdetasetから別のShared変数に格納しているため前に取得したdataset は開放してしまったのが原因でした。 ただ、 Shared変数はアプリケーション全体で保持される変数なのですね。 端末2台でやったらDataGridの内容が入れ替わってしまいました。 というわけでShared変数は廃止してsession変数で対応するようにします。 ありがとうございました。 |
1