新約聖書 テモテへの第一の手紙

読了。
パウロから弟子テモテに対する手紙。XX人への手紙シリーズは終わって、ここからは個人への手紙になるようである。
ただ内容はあまりこれまでと変わらず、説法的なものになっている。
テモテは使徒行伝の16章にも登場し、ルステラ(現在のトルコ)からベレヤ(現在のギリシャ)までパウロの旅に同行している。

「ASP.NETにおいて、static変数は「リクエスト単位」のグローバル変数『ではない』」ことへの対応で役立ちそうなコード

'Sharedフィールドを初期化
Dim oFields As FieldInfo() = GetType(clsGlobal).GetFields(BindingFlags.Public Or BindingFlags.Static)
For Each oField In oFields
    If oField.IsLiteral = True Then Continue For '定数はスキップ

    If oField.FieldType = GetType(String) Then
        oField.SetValue(Nothing, "")
    Else
        oField.SetValue(Nothing, If(oField.FieldType.IsValueType, Activator.CreateInstance(oField.FieldType), Nothing))
    End If
Next

新約聖書 テサロニケ人への第一の手紙

読了。
パウロからテサロニケに向けた布教。
テサロニケは現在のギリシャ第2の規模の都市「テッサロニキ
それぞれの部は出てくる順にだんだん、キリスト教に改心させる方向からすでにキリスト教を信じている人たちへの説法に切り替わっている気がする。

ASP.NETにおいて、static変数は「リクエスト単位」のグローバル変数『ではない』

http://kapijie.blog115.fc2.com/blog-entry-8.html

ASP.NETでstatic変数を扱う場合、変数のスコープをしっかり確認しておく必要があります。
ASP.NETの場合、static変数はASPという大きなプロセスの中に1つしか存在しません。
フォームアプリケーションと同じ感覚で使っていると、複数のユーザーから同時にアクセスがあった時に、大変なことになります。

ASP.NET で static変数 はサーバで動作している「プログラム全体」で共有する。
ASP.NETにおいて、static変数は「リクエスト単位」のグローバル変数『ではない』。
以下のようなページがあるとき、_staticNumはサーバ全体で1つの値を保持しており、表示される数値はアクセスされるごとに毎回カウントアップされていく。
これは別のリクエストだろうが、別ブラウザからのアクセスだろうが、別マシンからのアクセスだろうが関係なく、カウントアップされていく。

Public Class SamplePage
    Inherits System.Web.UI.Page

    Public Shared _staticNum As Integer = 0

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        _staticNum += 1
        Me.Response.Write(_staticNum)
    End Sub

End Class

対策

以下の対策を行うことで、static変数はリクエスト単位のグローバル変数であるかのように振る舞う。
static変数にThreadStatic属性を付けて宣言する。
さらにPage_Loadイベントでstatic変数の初期化を行う。



ThreadStatic属性をつけることで、あるリクエスト中に、別のリクエストがstatic変数を上書きしてしまうことを防止できる。別のリクエストは別スレッドで処理されるため。
スレッドは使い回される可能性があるため、リクエストごとに初期化をしないと前回の値が残ったままになる。
ごく稀に1つのリクエストが最初はスレッド1で処理されており、Loadイベント発生前に処理がスレッドBに引き継がれるということが起きるらしい。そのため、Page_Loadより前にThreadStatic属性static変数に格納された値はスレッドが切り替わって破棄される可能性がある。
http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html
https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=http%3A%2F%2Fpiers7.blogspot.com%2F2005%2F11%2Fthreadstatic-callcontext-and_02.html

お砂糖

VRChat内でのカップルの事、またはVRCユーザー同士で可愛がりあっている様子。
対義語としてお塩がある。
なにかをもじった語源があるわけではなく、甘々な様子を指したところから生まれた単語のようだ。

ASP.NETでクライアント(アクセス元)IPアドレスをIPv4で取得する方法

http://www.4guysfromrolla.com/articles/071807-1.aspx
System.Web.HttpContext.Current.Request.UserHostAddressでIPv6が取得されてしまう場合に、IPv6ではなくIPv4のアドレスを取得するには以下のようにする。

Public Shared Function GetIP4Address() As String
  Dim IP4Address As String = String.Empty

  For Each IPA As IPAddress In Dns.GetHostAddresses(HttpContext.Current.Request.UserHostAddress)
    If IPA.AddressFamily.ToString() = "InterNetwork" Then
      IP4Address = IPA.ToString()
      Exit For
    End If
  Next

  If IP4Address <> String.Empty Then
    Return IP4Address
  End If

  'ここは、IPv4が取得できなかったとき代わりにクライアントIPではなくホストIP(ASP.NETを実行しているマシンのIP)を取得するというコード
  'For Each IPA As IPAddress In Dns.GetHostAddresses(Dns.GetHostName())
  '  If IPA.AddressFamily.ToString() = "InterNetwork" Then
  '    IP4Address = IPA.ToString()
  '    Exit For
  '  End If
  'Next

  Return IP4Address
End Function

https://codeday.me/jp/qa/20190401/522769.html
そしてIPv4アドレスをサクッと取るのは実は無理らしい。

魔法のIPV4IPV6コンバータはありません。それらは完全に異なるプロトコルであり、
一方のアドレスは他方のアドレスに変換されません。
クライアントのIPV4アドレスを確実に取得したい場合は、クライアントがIPV4を介して
接続していることを確認する必要があります。



なぜか知らんが日本語で検索すると、ASP.NETでクライアントIPを取得するというタイトルで、ホストのIPv4アドレスを取得するコードを載せている誤った情報が出てくるので注意。
http://noritarou532.hatenablog.com/entry/2014/07/22/154523
https://www.aiik.net/2019/01/17/asp-net%E3%81%A7%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88ip%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B/