- PR -

セッション状態モードをStateServerに変更したら

1
投稿者投稿内容
よねちん
ベテラン
会議室デビュー日: 2002/09/18
投稿数: 55
投稿日時: 2005-06-07 16:51
セッション状態モードをInprocからStateServerに変更しました。
アウトプロセスによりワーカプロセスの負荷を軽減する為に。

取りあえず変更すればそれだけで良いと思いましたが・・・・
Session情報に構造体を代入する時に以下のエラーがでました。

セッション状態をシリアル化できません。セッション状態モードが 'StateServer'
か 'SQLServer' の時は、シリアル化できないオブジェクトまたは MarshalByRef
オブジェクトは許可されません。

なんだこりゃと思って調べたら・・・MicroSoftのバグでした。
http://support.microsoft.com/default.aspx?scid=kb;ja;312112

そこで解決方法としてClassをSerializableにするようにと書いてあるのですが・・・

Classで宣言している場所には
<Serializable()>Public Class MyClass
'Class code
End Class

こんな感じにして宣言を追加し

構造体で宣言している場所には

<Serializable()> Public Structure rsdata

Dim txt1 As String
Dim txt2 As String

   End Structure

と宣言してあげれば良いのがわかりました。

ではWEBコントロールの場合にはどうやればいいのでしょうか?

現在セッションに

Session("SelectGrid") = myGrid.SelectedItem

とかしているところが結構あるのですが・・・・そこでエラーになって
しまいます。
WEBコントロールをSerializableするにはどうすればいいでしょうか?

教えてください。
にしざき
ぬし
会議室デビュー日: 2003/06/30
投稿数: 304
投稿日時: 2005-06-07 17:02
できません。
仮にシリアライズできたとしても、デシリアライズしたものは Grid の要素にはならないため、無意味だと思います。

発想を転換して、「そのSelectedItem を特定する値」を保持するようにするとよいでしょう。
よねちん
ベテラン
会議室デビュー日: 2002/09/18
投稿数: 55
投稿日時: 2005-06-07 18:13
2重投稿してみたいなのでこちらに返信はまとめます。

にしざきさん返信ありがとうございます。

>発想を転換して、「そのSelectedItem を特定する値」を保持するようにするとよいでしょう

Session("SelectGrid") = myGrid.SelectedItem



Session("SelectGrid_AAA") = myGrid.SelectedItem.Cells("AAA").text
Session("SelectGrid_BBB") = myGrid.SelectedItem.Cells("BBB").text

こんな感じにすればいいってことですよね?

本数がすごくあって、もし特定する値に変えるように変更すると
呼び出し側の画面も当然変えていかなければならない為に莫大な
修正工数がかかってしまいます。
修正パッチが欲しい(泣・・・)

button999さん返信ありがとうございます。

>回答ではないですが、WebコントロールはMVCでいうViewにあたるので
>永続化されることを想定してないのだと思います。

今回のセッションのアウトプロセスはセッション情報をワーカプロセスから
分離したかったのと、マルチCPUなのでWEBガーデンを後にする為に行って
いるところなのです(WEBガーデンはアウトプロセスでしかできないので)
それゆえに、これを解決していかねばなりません。

なにか修正工数がかからない良い修正方法がないでしょうか?




Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-06-07 19:32
> なんだこりゃと思って調べたら・・・MicroSoftのバグでした。
 バグって、ああた、ちゃんと読もうよ(^-^;

 これ、エラーにならないのがバグで、エラーになるのは正常な動作ですよ。
 セッション変数をアウトプロセスやSQL Serverにしまうということは、自分でメモリを抱えていれば良かったものを、他人に預けてやらなければならなくなります。この、"預ける"行為を、シリアル化という手順を通して行います。


 それで、シリアル化する必要があるのは、SelectedItemだけですよね。Webコントロールそのものをシリアル化する必要はないですよね。SelectedItemには、何が入っていますか?


編集追加
引用:

今回のセッションのアウトプロセスはセッション情報をワーカプロセスから分離したかったのと、マルチCPUなのでWEBガーデンを後にする為に行っているところなのです(WEBガーデンはアウトプロセスでしかできないので)
それゆえに、これを解決していかねばなりません。

なにか修正工数がかからない良い修正方法がないでしょうか?


最初に調べておけば、そんな手間かけずに済んだのに。。。
Webガーデンは構成したことがありませんが、同じように「こういうことやるとだめ」的なことがあると思います。先に調べましょう。

[ メッセージ編集済み 編集者: Jitta 編集日時 2005-06-07 19:35 ]
todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2005-06-07 19:59
引用:

>発想を転換して、「そのSelectedItem を特定する値」を保持するようにするとよいでしょう

Session("SelectGrid") = myGrid.SelectedItem



Session("SelectGrid_AAA") = myGrid.SelectedItem.Cells("AAA").text
Session("SelectGrid_BBB") = myGrid.SelectedItem.Cells("BBB").text

こんな感じにすればいいってことですよね?




たとえば、プライマリーキーだけを保持して、他のフィールドはDBから読み込むとか。

値を保持する方法も色々あります。
ポストバックであればViewStateが使えるし、画面遷移であればQueryStringが使えます。

メモリを使っているアプリの調査方法
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=21797&forum=7&2

の解決策としてセッション管理をStateServerに変更するのでしょうか?

クラスや構造体を無闇にSession変数に保存しているのであれば、そこを見直すべきでしょう。
Session変数の使い方が不適切であれば、StateServerにすることでパフォーマンスが落ちるだけだと思います。
よねちん
ベテラン
会議室デビュー日: 2002/09/18
投稿数: 55
投稿日時: 2005-06-07 21:47
Jittaさん返信ありがとうございます。

> これ、エラーにならないのがバグで、エラーになるのは正常な動作ですよ。
> セッション変数をアウトプロセスやSQL Serverにしまうということは、自分でメモリを抱えていれば良かったものを、他人に預けてやらなければならなくなります。この、"預ける"行為を、シリアル化という手順を通して行います。

読み違いました。[BUG]で出ていたのと解決方法にシリアル化しなさいと
書いてあったので取り違いました。

>それで、シリアル化する必要があるのは、SelectedItemだけですよね。Webコントロールそのものをシリアル化する必要はないですよね。SelectedItemには、何が入っていますか?

はい。コントロールそのものをシリアル化する必要がありませんが
SELECTITEMの内容をごっそり送りたいのです。
でも結局は受け側で使用している値なんかを調べて送り側は分解して
送らなければ駄目なんでしょうか?

>最初に調べておけば、そんな手間かけずに済んだのに。。。
>Webガーデンは構成したことがありませんが、同じように「こういうことやるとだめ」的なことがあると思います。先に調べましょう。

実は運用に入ってからお呼びがかかりました(^^;
確かにおっしゃるとおりで事前に調査が必要ですね。
大規模なシステムを組む上での環境設定などが大事
だということをど痛烈に実感しています。
でも調査する期間がなかなか取れないというのと短
納期というのが実情でもあるんですよね。
す。


ぬしさん返信ありがとうございます。

>たとえば、プライマリーキーだけを保持して、他のフィールドはDBから読み込むとか。

>値を保持する方法も色々あります。
>ポストバックであればViewStateが使えるし、画面遷移であればQueryStringが使えます。

デバックの工数がないんです・・・(^^;

メモリを使っているアプリの調査方法
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=21797&forum=7&2

>の解決策としてセッション管理をStateServerに変更するのでしょうか?

プログラムの見直しもした上で環境も変更していこうと
思ってます。

今回のアウトプロセス化は
・セッション情報を別管理にしておき、ワーカプロセスがメモリを取り過ぎて
 memoryLimitにより落とされた時でも、セッション情報が消えないのでログイン
 などをやりなおさずにユーザはそのまま業務ができるというのが一番大きな理由
 ですかね。
 とにもかくにも現在はワーカプロセスが落ちるたびにユーザはログインしなおし
 を行い出戻り工数が増大していますから。
 元を直すのも当然なのですが、今の現状を少しでも良い環境をユーザに使って
 もらいたいというのがあります。

>クラスや構造体を無闇にSession変数に保存しているのであれば、そこを見直すべきでしょう。
>Session変数の使い方が不適切であれば、StateServerにすることでパフォーマンスが落ちるだけだと思います。

そうですね。なのでASPNET_STATE.EXEの膨らみ具合も見て調査を進めるつもりです。
ただセッションはあまり乱用されていないのが設定を変えてからわかりました。
ワーカプロセスだとセッションでメモリが増えているのかわからなかったので目に
見えてわかるだけでも調査にはなります。

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-06-08 20:48
> デバックの工数がないんです・・・(^^;
 ないからといって、付け焼き刃にすると、後でもっと痛い思いをします。例えば虫歯の治療と同じです。初期に治療しておけば、軽い治療ですみますが、進んでから治療すると、大変痛い思いをすることになります。


 手っ取り早くするなら、DataGridItemを引数とするコンストラクタを持った、シリアライズ可能なクラスを作る、でしょうか。TypeConverterも作って、DataGridItemに変換できるようにしておけば、取り出し側は触る必要はないでしょう。
 でも、独自クラスへの変換は良いとして、DataGridItemへなんて、どうやって変換するんだ?
_________________
よねちん
ベテラン
会議室デビュー日: 2002/09/18
投稿数: 55
投稿日時: 2005-06-09 09:02
Jittaさん返信ありがとうございます

>手っ取り早くするなら、DataGridItemを引数とするコンストラクタを持った、シリアライズ可能なクラスを作る、でしょうか。

そうですよね。

>でも、独自クラスへの変換は良いとして、DataGridItemへなんて、どうやって変換するんだ?

はいおっしゃる通りで・・・・
CELLSの中身はDataGridの中で設定されたもので可変ですので
それをどうやって定義すればいいか分からずに困ってます。
基本的には無理なんでしょうね。
現在、InprocからServerStateに変えなければならないプログラム
の洗い出しをしています。
現在77本中22本が修正対象となってます。
プログラムを組替えるしかないのでしょうかね。
1

スキルアップ/キャリアアップ(JOB@IT)