Open4

Asp.netにおける非同期処理のメモ

Kouta WakamatsuKouta Wakamatsu

個人的な非同期処理に関するメモです

そもそもなんで非同期処理にしたほうがいいかとか、注意点とか
https://qiita.com/ishiyama0530/items/faacf1aa0bd8c3a07141
公式情報も
https://learn.microsoft.com/ja-jp/aspnet/web-forms/overview/performance-and-caching/using-asynchronous-methods-in-aspnet-45
書き方とか
https://zenn.dev/vatscy/articles/ba2263bdfadfeb805379

web formsで非同期対応するときの設定

・PageディレクティブのAsyncプロパティをtrueにする

<%@ Page Language="VB" CodeBehind="~" Inherits="~" Async="true" %>

・web.configにUseTaskFriendlySynchronizationContextを追加(これはいらないかも・・)

<appSettings>
	<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>

注意点とか

・asyncfuncをawaitなしで呼び出した場合、呼び出し元の処理のほうが早くおわったら(ページの読み込み全体?)サーバーに処理をなげてても中断される。

Private Async Function TestProcAsync() As Task
    '10秒まつ
    Await Task.Delay(10000)
    'なんか処理
    Debug.Print("OK")
End Function
Protected Async Sub Button_1_Click(sender As Object,e As EventArgs)
    TestProcAsync()
    Debug.Print("ClickEnd")
End Sub
Protected Async Sub Button_2_Click(sender As Object,e As EventArgs)
    Await TestProcAsync()
    Debug.Print("ClickEnd")    
End Sub

こんな感じだと1を実行するとClickEndのみ書き出されてポストバックはおわり、OKは書き出されない。
ボタン2のクリックはOK→ClickEndで書き出される。
実際にはOKの部分の処理が、SQLの実行とかだと処理が非同期でサーバーになげてて勝手に実行までいくものと勘違いしていた。

・Async void(Async Sub)はコントロールイベントのみにする

普通のSub関数を非同期化するときはFunctionにしてTaskを返すようにする
この辺とか
https://neue.cc/2013/10/10_429.html
公式にもかいてる
https://learn.microsoft.com/ja-jp/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming

※webformsだとページライフサイクルが乱れる可能性があるのでRegisterAsyncTaskを使用するのが吉かも

・Resultで同期的な処理にしない

AsyncメソッドはResultとかWaitとかで同期的に処理する用に書くことができるが、webアプリだとスレッドのデッドロックを起こす可能性があるので、使用しないほうがよい。
色々書き方があるけど、async/awaitで基本的には書きましょうということ。

あと、非同期と並列は別物です。。。

Kouta WakamatsuKouta Wakamatsu

sqlCommandのExecuteReaderとかExecuteNonQueryにもAsyncがあるので、使った方がいいかも。
でもあんまり記事はでてこない・・・