DOBON.NETプログラミング道掲示板

■ 「新規作成」から投稿できます。
■ マルチポストされた投稿を見つけたときは、その投稿に返信することによりご報告ください。その際は匿名で投稿し、マルチポストされている場所を併記してください。
■ スパム対策のため、メールアドレスの先頭に"_"という文字が付加されています。
RSS 2.0 RSS 2.0 | RSS 0.91 | 携帯電話用 | 自分専用のアイコンを使用するには | 掲示板への要望 | 管理人に連絡 | お気楽掲示板
■ 24時間以内に作成されたスレッドは New で表示されます。
■ 24時間以内に更新されたスレッドは UpDate で表示されます。

記事リスト ( )内の数字はレス数
NomalWindowsMediaPlayerで次のURLを指定しても反映されない。(2) | Nomal"−"を縦書きにしたい(9) | Nomal.NET6.0 のWinFormにWPFのユーザーコントロールを配置したい(4) | NomalDataGridViewの列にコンボボックスを表示する(2) | Nomalデータグリッドビューの特定の列ヘッダの色(2) | NomalVB-Report10→11への移行(4) | Nomalデフォルトプリンタの用紙向き変更(0) | NomalASP.net デバッグ時の .js ファイルの変更が反映されない(1) | NomalpictureBoxとlabelの重ね合わせ(2) | NomalWindowsエクスプローラへのドロップ先フォルダの取得(4) | Nomal入力値を元に描画させたい(2) | NomalVBで開いたExcelでのイベントを取得するには(4) | NomalデザイナでSystemColorsのような色一覧から選択できるようにしたい(0) | NomalTaskの入れ子の待ち方2(4) | NomalTaskの入れ子の待ち方(5) | NomalVisualStudio2019 以降の検索ダイアログが正常に動作しない(2) | NomalUsingの使い方が間違っている?(4) | Nomal//./の意味は?(2) | Nomalバイナリーファイルの結合と分解(2) | NomalVSTOとWebView2の共存って可能?(2) | Nomal表の最後の行の下にDropできない(1) | NomalCookieの勉強を始めました。(2) | NomalDataGridViewの特定セルにボタンを配置する方法(3) | NomalDataGridViewのセル結合部分にボタンを表示する方法(3) | Nomal複数のPageに分かれる場合のスクレ―ピング(6) | NomalTask.Runの使い方(4) | NomalPictureBox のサイズを設定する(2) | NomalProcessクラスMainModuleプロパティでアクセス拒否(3) | NomalLINQでControlsをEnable=Falseに設定(3) | Nomalランダムファイルを高速化させたい(5) | Nomalプロセス間の通信(相互)(2) | NomalC#をVBに変換する方法が分かりません(1) | NomalPictureBoxに動的に画像を表示する(1) | NomalYahooのHPで、検索文字の入力ができない(3) | NomalWebView2のEncodeの問題?(5) | NomalWinFormでChromeをSeleriumで操作しているが、Closeの仕方(2) | Nomal印刷部数の固定(1) | NomalWinformでのDataGridView Comboboxのデータ追加削除が出来ない(3) | Nomalプログラムについて。(2) | Nomal拡張子関連付けのサンプルで削除時 例外発生(1) | Nomalユーザーコントロールをフォームで使用した時のエラー(6) | NomalマルチページTIFFをSelectActiveFrameでページ指定するとエラーが発生する(12) | Nomal画像の大きさを取得するには(4) | Nomalファイルがドライブ内で占有する容量(3) | NomalC#FormのXボタンイベントで、e.Cancel が使えない(2) | NomalAxWindowsMediaPlayerでプレイリストの途中から再生するには(2) | NomalWebView2でJavaScriptの実行の終了イベント(4) | NomalDataTableのDataRowVersion毎のInt型値の比較がうまくいかない(5) | NomalGPTかMBRを判断したい(2) | Nomalアセンブリ言語について。(1) | Nomalマクロについて。(3) | NomalDLL内のスレッドからイベントを発行すると、受信したフォームでラベルが更新できない(3) | Nomalアセンブリ言語について。(20) | Nomalシステムコールについて。(2) | Nomal Parallel.Forで思ったより早くならない(5) | NomalAngleSharp.Scripting.JavaScriptの使い方(2) | NomalDataAdapterで2回目のUpDateが出来ない(6) | NomalForm1イベントの選択が出来なくなりました。(9) | Nomalデザーナー時の継承先formのサイズ(0) | Nomalコンソールではなくテキストボックスに文字列を出力したい(7) | NomalAngleSharpのクエリー文2(4) | Nomalコーディングについて。(3) | Nomaldll修正時、それを参照しているexeのリビルド要否(2) | NomalAngleSharpのクエリー文(2) | Nomalデフォルトプロパティを使いたい(6) | Nomalテキストボックスでの制御(7) | NomalUSBカメラをピクチャボックスに表示(3) | Nomal二次元配列内の文字の置き換え(3) | Nomalcolor型を引数にする方法(2) | NomalVSプロジェクト作成方法の違いによる、プラグイン機能を持つアプリケーションへの影響について(6) | NomalInputボタンが押せない(4) | NomalWebBrowserのDocumentCompletedイベントの切り替え(3) | NomalEndConnectでのエラー(2) | Nomalボタンクリック時のLeaveイベントについて(1) | Nomalエクセルのデータを配列に読込んだ時の配列要素番号について(2) | Nomalorder by で抽出したデータをDataTableに入れてForEachでDataRow取得した際の順番(2) | Nomal非同期プログラミング時のConsole.WriteLineの動作(4) | NomalC#からストアドにDecimalを渡すと値が丸められる(4) | Nomalインスタンスの型を文字列で指定したい(2) | NomalSendKeys.Sendが効いていない(2) | Nomal他のプロジェクトのコントロールがツールボックスに表示されない(3) | Nomal複数のテキストボックス間のTextChangedイベントが相互干渉しないようにしたい(9) | Nomal呼び出し元によってWebApi側の処理速度に差が出る(1) | NomalPanelのDock=Topだとうまくいかない。代替案。(2) | Nomal.NetでのIPv6の比較(5) | Nomal.Net 5.0 におけるDLL参照問題?(7) | Nomal追加コントロールのtabindex値を既存の間に設定する方法(1) | NomalVB.net非同期処理でtextboxに出力したい(2) | NomalToolStripStatusLabelの空白部分を埋めたい(2) | NomalOracle への OleDb 接続に失敗する(3) | Nomal正規表現で株価を取得したい(1) | NomalVB.NETで作成したDLLをVB6.0から呼び出す(3) | Nomalデザイナで編集・チェックアウトキャンセルすると(3) | Nomal親スレッドへ処理の移譲(7) | NomalクラスによるGetBytes関数のエンディアンの違い(2) | Nomal[VB.NET]Excelのプロセスが終了しない(2) | NomalC#をVBに変換した際の強制的な参照渡し(2) | Nomal.Net 5.0 におけるServiceControllerの代替クラス(3) | Nomal新たにshowしたフォームでのボタンのクリック(5) | NomalVB.NETからRDゲートウェイを利用したリモートデスクトップ接続(4) |



■記事リスト / ▼下のスレッド
■35008 / 親記事)  入力値を元に描画させたい
□投稿者/ はな 一般人(1回)-(2022/02/14(Mon) 08:46:08)
  • アイコン環境/言語:[VB.NET] 
    分類:[.NET] 

    DatagridViewでスケジュール管理のようなものを作成しています。

    入力された日付を元にCellPaintingでバーを描画しているのですが、
    入力後にイベントは実行されているのですが描画がされません。

    手動でスクロールするなりすれば描画はされるのですが、、、

    入力後に描画させる方法はありませんか?
違反を報告
引用返信

▽[全レス2件(ResNo.1-2 表示)]
■35009 / ResNo.1)  Re[1]: 入力値を元に描画させたい
□投稿者/ shu 大御所(496回)-(2022/02/22(Tue) 17:14:00)
  • アイコンNo35008に返信(はなさんの記事)


    https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.datagridview.invalidatecell?view=windowsdesktop-6.0

    DataGridView.InvalidateCell
    で再描画されないでしょうか?
違反を報告
引用返信
■35025 / ResNo.2)  Re[2]: 入力値を元に描画させたい
□投稿者/ はな 一般人(2回)-(2022/03/28(Mon) 11:30:37)
  • アイコンNo35009に返信(shuさんの記事)
    >

    ありがとうございます。試してみます。
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-2]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35004 / 親記事)  VBで開いたExcelでのイベントを取得するには
□投稿者/ ぶぶ 一般人(1回)-(2022/02/07(Mon) 17:40:36)
  • アイコン環境/言語:[Windows10 vb.net Excel 2007 ] 
    分類:[.NET] 

    VB.netでExcelを起動し、VBでの操作により、Excelを編集するプログラムを
    作成しています。

    この場合、Excelでのイベント(クリックや右クリック、ダブルクリックなど)を

    VB側で取得する方法はありますか?

    Excelは毎回新規で作成して編集するので、Excel側に組み込むことは考えていません。

    よろしくお願いいたします。
違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■35005 / ResNo.1)  Re[1]: VBで開いたExcelでのイベントを取得するには
□投稿者/ 魔界の仮面弁士 大御所(1415回)-(2022/02/07(Mon) 18:31:11)
  • アイコンNo35004に返信(ぶぶさんの記事)
    > この場合、Excelでのイベント(クリックや右クリック、ダブルクリックなど)を
    > VB側で取得する方法はありますか?
    > Excelは毎回新規で作成して編集するので、
    > Excel側に組み込むことは考えていません。

    出来るかもしれませんが、かなり面倒だとは思います。

    RelaxTools などのように、Excel 側のアドインとして
    実装する方向についても、併せて検討してみては如何でしょうか。
    https://software.opensquare.net/relaxtools/


    技術的には OLE オートメーションによって、Excel 側で発生したイベントを
    VB 側で捕らえる事もできるのですが、Excel.Application オブジェクトで
    Excel のイベントで使えそうなマウス絡みのイベントといっても、直接的には
     SheetBeforeDoubleClick イベント
     SheetBeforeRightClick イベント
     SheetSelectionChange イベント
    ぐらいしか無いと思います。

    また、Excel がセル編集モードになったり、ダイアログの表示中などは、
    Excel 側で行った操作を、VB 側で受け取ることができません。


    Excel.Application オブジェクトのイベントを捕らえる以外の方法としては、
    RawInput あるいは DirectInput を用いて、マウスボタンの押下を
    捕らえるという手法があります。

    http://bbs.wankuma.com/index.cgi?mode=al2&namber=97964&KLOG=170
    http://bbs.wankuma.com/index.cgi?mode=al2&namber=92410&KLOG=159

    とはいえこれも、ボタンが押されたという事を知ることができる程度で、
    その時のマウス座標が、Excel 上のどの場所を指しているのかについては
    別途判断せねばなりません。要件を満たすまでに昇華するのは難しいかと。
違反を報告
引用返信
■35006 / ResNo.2)  Re[2]: VBで開いたExcelでのイベントを取得するには
□投稿者/ ぶぶ 一般人(2回)-(2022/02/08(Tue) 10:38:01)
  • アイコン魔界の仮面弁士様

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

    やりたいイベントとしても、セルをクリックまたは右クリック等がされたときに、
    そのセルの内容から、処理をしたい。位のものなので、教えていただいたリンクを
    基に試行してみたいと思います。

    > 技術的には OLE オートメーションによって、Excel 側で発生したイベントを
    > VB 側で捕らえる事もできるのですが、Excel.Application オブジェクトで
    > Excel のイベントで使えそうなマウス絡みのイベントといっても、直接的には
    >  SheetBeforeDoubleClick イベント
    >  SheetBeforeRightClick イベント
    >  SheetSelectionChange イベント
    > ぐらいしか無いと思います。

    これで、十分なのではないかとも思うのでやってみます。


    >
    > また、Excel がセル編集モードになったり、ダイアログの表示中などは、
    > Excel 側で行った操作を、VB 側で受け取ることができません。

    この場合は、処理の必要はないので、大丈夫ではないかと思っています。
    >
    > Excel.Application オブジェクトのイベントを捕らえる以外の方法としては、
    > RawInput あるいは DirectInput を用いて、マウスボタンの押下を
    > 捕らえるという手法があります。
    >
    > http://bbs.wankuma.com/index.cgi?mode=al2&namber=97964&KLOG=170
    > http://bbs.wankuma.com/index.cgi?mode=al2&namber=92410&KLOG=159
    >
    > とはいえこれも、ボタンが押されたという事を知ることができる程度で、
    > その時のマウス座標が、Excel 上のどの場所を指しているのかについては
    > 別途判断せねばなりません。要件を満たすまでに昇華するのは難しいかと。

    検索してもなかなかいい情報に巡り合えなかったので、少し糸口が見えました。
    いつもありがとうございます。

違反を報告
引用返信
■35007 / ResNo.3)  Re[3]: VBで開いたExcelでのイベントを取得するには
□投稿者/ 魔界の仮面弁士 大御所(1416回)-(2022/02/08(Tue) 18:05:17)
  • アイコンNo35006に返信(ぶぶさんの記事)
    > やりたいイベントとしても、セルをクリックまたは右クリック等がされたときに、
    > そのセルの内容から、処理をしたい。位のものなので、教えていただいたリンクを
    > 基に試行してみたいと思います。

    それであれば、
     Private WithEvents app As Excel.Application
    な変数に、Excel.Application のインスタンスをセットすることで
    イベントを受け取ることができるはずです。
    ワークブックが明確な場合は
     Private WithEvents book As Excel.Workbook
    を使うこともできます。


    Excel の操作方法は既にご存知かもしれませんが、
    とりあえずこのあたりを紹介しておきます。
    "Microsoft Excel x.x Object Library" への参照設定が必要です。
    http://hanatyan.sakura.ne.jp/vb2005/vb2013excel01.htm


    一応、参照設定なしでイベントを捉える方法も貼っておきます。
    参照設定する方法に比べると手間がかかるので、お奨めはしませんけど。
    https://www.petitmonte.com/bbs/answers?question_id=28859


    今回は VB で開いた Excel とのことですが、もし、すでに起動済みの
    Excel を拾う場合は、ROT(Running Object Table)から辿って取得できます。
違反を報告
引用返信
■35017 / ResNo.4)  Re[4]: VBで開いたExcelでのイベントを取得するには
□投稿者/ ぶぶ 一般人(3回)-(2022/03/09(Wed) 15:39:26)
  • アイコン魔界の仮面弁士様

    追加の情報までありがとうございました

    なんとかイベントも拾えました。


    抜粋ですが、
    <===================Form
    Option Explicit On
    Public Class frm_test
    Private Sub mnu_AAA_Click(sender As System.Object, e As System.EventArgs) Handles mnu_AAA.Click

    途中略


    ' ----- Excelのイベントを拾えるようにする
    ExObject.appevent = xlApp

    End Sub
    End Class
    <===================Module
    Imports Microsoft.Office.Interop
    Imports Microsoft.Office.Core
    Imports System.Runtime.InteropServices

    Module Bas_Excel
    Public xlApp As Excel.Application
    Public xlClose As Boolean
    Public xlChart As Excel.Chart

    Public xlBooks As Excel.Workbooks
    Public xlBook As Excel.Workbook
    Public xlSheets As Excel.Sheets
    Public xlSheet As Excel.Worksheet

    Public ExObject As New Cls_ExcelClick

    End Module



    <===================Class
    Public Class Cls_ExcelClick

    Public WithEvents appevent As Excel.Application

    Private Sub appevent_SheetBeforeDoubleClick(Sh As Excel.Worksheet, Target As Microsoft.Office.Interop.Excel.Range, _
    ByRef Cancel As Boolean) Handles appevent.SheetBeforeDoubleClick
    ' ' ----- Excelがダブルクリックされた時の処理
    xlSheet = xlApp.ActiveSheet
    If Sh.Name = xlSheet.Name Then

    ' ----- ダブルクリックが対象物の時処理をする
    Shell("c:\test\Bin\Sampletest.exe", AppWinStyle.NormalFocus)
    Else
    ' ----- 対象ではないので、何もしない
    End If
    End Sub
    End Class

    切り取っているので、わかりにくいかもしれません。

    解決をつけさせていただきます。

    ありがとうございました。

解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■35003 / 親記事)  デザイナでSystemColorsのような色一覧から選択できるようにしたい
□投稿者/ masa 一般人(1回)-(2022/02/02(Wed) 18:58:50)
  • アイコン環境/言語:[C# WindowsForms .NET Framework 4.5 VisualStudio2019 Windows10 64bit] 
    分類:[.NET] 

    お世話になっております。
    WindowsFormsアプリケーションのコントロールにおいて、
    デザイナでColor型プロパティをSystemColorsのような色一覧から選択できるようにし、
    自動生成されるコードにも反映されるようにしたいと考えています。

    具体的には下記のようなクラスを作成し、適当なフォームにTestControlを貼り付けた際に、
    プロパティウィンドウではBackColor/ForeColorをBackground/Foregroundの選択肢から選択、
    自動生成されるコードではForeColor = ThemeColors.Background;のようにしたいですが、
    ForeColor = Color.Whiteが自動生成されてしまいます。

    どなたかご助言いただけますでしょうか。
    よろしくお願いいたします。

    enum Themes
    {
    Dark,
    Light
    }

    class ThemeColors
    {
    public static Themes Theme { get; set; } = Themes.Light;

    public static Color Background => (Theme == Themes.Light ? Color.White : Color.Black);
    public static Color Foreground => (Theme == Themes.Light ? Color.Black : Color.White);
    }

    class ThemeColorConverter : TypeConverter
    {
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true;

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) => new StandardValuesCollection(typeof(ThemeColors).GetProperties().Where(p => p.PropertyType == typeof(Color)).Select(p => p.Name).ToList());

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
    if (sourceType == typeof(string)) return true;
    return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
    if (value is string) return typeof(ThemeColors).GetProperty(value.ToString())?.GetValue(null);
    return base.ConvertFrom(context, culture, value);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
    if (destinationType == typeof(InstanceDescriptor)) return true;
    return base.CanConvertTo(context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
    if (destinationType == typeof(InstanceDescriptor)) return new InstanceDescriptor(typeof(ThemeColors).GetProperty(value.ToString()), null);
    return base.ConvertTo(context, culture, value, destinationType);
    }
    }

    class TestControl : Control
    {
    [Editor(typeof(UITypeEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ThemeColorConverter))]
    public override Color BackColor { get => base.BackColor ; set => base.BackColor = value; }

    [Editor(typeof(UITypeEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ThemeColorConverter))]
    public override Color ForeColor { get => base.ForeColor ; set => base.ForeColor = value; }
    }
違反を報告
引用返信



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34997 / 親記事)  Taskの入れ子の待ち方2
□投稿者/ Wan 付き人(56回)-(2022/01/06(Thu) 17:05:10)
  • アイコン環境/言語:[VisualBasic2019 Windows10 Basic Framework4.7.2] 
    分類:[.NET] 

    「Taskの入れ子の待ち方」の続きです。
    子Taskをラムダ式からメソッドへのデリゲートに変え、Task.Runにキャンセルトークンを渡すように変更したコードが次の通りです。
    Dim tokenSource As New CancellationTokenSource
    Private Async Sub Button6_Click(sender As Object, e As EventArgs)
    tokenSource = New CancellationTokenSource
        Debug.Print($"StartTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
        Try
          Await Task.Run(AddressOf Test, tokenSource.Token)
        Finally
          tokenSource.Dispose()
        End Try
        Debug.Print($"FinishTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
    End Sub
    
    Async Function Test() As Task
    Dim i As Integer = 0
        Debug.Print($"子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
        Dim 孫Task As Task = Task.Run(
          Sub()
              Dim j As Integer = 0
                Debug.Print($"孫子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
                While j < 7
                  If token.IsCancellationRequested Then
                      Debug.Print("孫Taskは、停止しました。")
                        Exit While
                    End If
                    Thread.Sleep(500) '0.5秒待つ
                    Debug.Print($"孫TaskCount:{j}")
                    j += 1
                End While
            End Sub)
        While i < 5
          If token.IsCancellationRequested Then
              Debug.Print("子Taskは、停止しました。")
                Exit While
            End If
          Thread.Sleep(500) '0.5秒待つ
            Debug.Print($"子TaskCount:{i}")
            i += 1
        End While
        Await 孫Task
    End Function
    すると、当然、Testメソッドにtokenの引数が無いので、Testメソッド側でtokenが認識できません。当然のように思えます。
    ネットでググっても、Testメソッドの引数にキャンセルトークンを渡しているものばかりが見つかります。
    ってことは、Task.Runで、キャンセルトークンを渡す必要性がそもそも無いということになるように思いますが、間違っていますでしょうか?何のためにキャンセルトークンをTask.Runで渡すのでしょうか?
    「Taskの入れ子の待ち方」では、ラムダ式で渡していたので、Task.Runでtokenを渡さなくてもメインスレッドのtokenの状態を確認することができました。
    Task.Runで、キャンセルトークンを渡しているので、孫タスク側で何か?うまい方法でtokenを認識する方法は?無いものでしょうか?
    質問の意図が通じますでしょうか?
    宜しくお願い致します。
    

違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■34998 / ResNo.1)  Re[1]: Taskの入れ子の待ち方2
□投稿者/ Wan 付き人(57回)-(2022/01/06(Thu) 17:57:32)
  • アイコン
    因みに、Task.Runにキャンセルトークンを渡さないで、ラムダ式で引数としてtokenを渡す場合は、次のようにすると上手くいきました。
    Private Async Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
            tokenSource = New CancellationTokenSource
            Debug.Print($"StartTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
            Try
                Await Task.Run(Function()
                                   Return Test2(tokenSource.Token)
                               End Function)
            Finally
                tokenSource.Dispose()
            End Try
            Debug.Print($"FinishTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
        End Sub
    
        Async Function Test2(ByVal token As CancellationToken) As Task
            Dim i As Integer = 0
            Debug.Print($"子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
            Dim 孫Task As Task = Task.Run(
                            Sub()
                                Dim j As Integer = 0
                                Debug.Print($"孫子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
                                While j < 7
                                    If token.IsCancellationRequested Then
                                        Debug.Print("孫Taskは、停止しました。")
                                        Exit While
                                    End If
                                    Thread.Sleep(500) '0.5秒待つ
                                    Debug.Print($"孫TaskCount:{j}")
                                    j += 1
                                End While
                            End Sub)
            While i < 5
                If token.IsCancellationRequested Then
                    Debug.Print("子Taskは、停止しました。")
                    Exit While
                End If
                Thread.Sleep(500) '0.5秒待つ
                Debug.Print($"子TaskCount:{i}")
                i += 1
            End While
            Await 孫Task
        End Function

違反を報告
引用返信
■34999 / ResNo.2)  Re[1]: Taskの入れ子の待ち方2
□投稿者/ Hongliang 大御所(618回)-(2022/01/06(Thu) 17:59:07)
  • アイコン// Taskを返すメソッドは基本的にAsyncサフィクスをつけてTestAsyncのようにすると見通しがいいです。

    提示されたソースによればTest自体tokenを使っているので、そもそもそのコードではコンパイルエラーになりますよね。
    孫TaskにCancellationTokenを渡したいのであれば、Testがそれを提供する必要があるでしょう(まあCancellationTokenSourceから直接取るというケースもありますが)。
    なので、TestもCancellationTokenを引数に取る必要があるでしょう。

    引数を取るメソッド、例えばFunction Test(CancellationToken)に対してTask.Runするのであれば、ラムダ式を1つ挟むようにすればいいです。
    Task.Run(Function() Test(token), ...)
違反を報告
引用返信
■35000 / ResNo.3)  Re[2]: Taskの入れ子の待ち方2
□投稿者/ Hongliang 大御所(619回)-(2022/01/06(Thu) 18:01:10)
  • アイコンつまり質問内容としては、Task.Run(..., token)のこのCancellationTokenの必要性ということですか。
    このCancellationTokenについては以下のページなどを参考にしてください。
    https://ricka.co.jp/?p=16922
違反を報告
引用返信
■35001 / ResNo.4)  Re[3]: Taskの入れ子の待ち方2
□投稿者/ Wan 付き人(58回)-(2022/01/06(Thu) 18:30:00)
  • アイコンHongliangさん
    初歩的な質問に対して、丁寧な御指南有難うございます。
    教えて頂いた、HPを含め、教えていたた内容について、熟慮したいと思います。
    また、疑問が出た場合は、お手数ですが、御指南の程よろしくお願い致します。
    有難う御座いました。
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]



■記事リスト / ▲上のスレッド
■34990 / 親記事)  Taskの入れ子の待ち方
□投稿者/ Wan 付き人(51回)-(2022/01/06(Thu) 10:34:44)
  • アイコン環境/言語:[VisualBasic2019 Windows10 Basic Framework4.7.2] 
    分類:[.NET] 

    下記のコードは、ボタン5を押すと子タスクと孫タスクが起動して、子タスクが、孫Taskのj>7のFalseを待って、終了する積りで書いたものです。
    Dim tokenSource As New CancellationTokenSource
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    tokenSource.Cancel()
    End Sub
    Private Async Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
    tokenSource = New CancellationTokenSource
        Dim token As CancellationToken = tokenSource.Token
        Debug.Print($"StartTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
        Try
          Await Task.Run(
              Async Sub()
                  Dim i As Integer = 0
                    Debug.Print($"子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
                    Dim 孫Task As Task = Task.Run(
                      Sub()
                          Dim j As Integer = 0
                            Debug.Print($"孫子Task ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
                            While j < 7
                              If token.IsCancellationRequested Then
                                  Debug.Print("孫Taskは、停止しました。")
                                  Exit While
                                End If
                                Thread.Sleep(500) '0.5秒待つ
                                Debug.Print($"孫TaskCount:{j}")
                                j += 1
                            End While
                        End Sub)
                    While i < 5
                      If token.IsCancellationRequested Then
                          Debug.Print("子Taskは、停止しました。")
                            Exit While
                        End If
                        Thread.Sleep(500) '0.5秒待つ
                        Debug.Print($"子TaskCount:{i}")
                        i += 1
                    End While
                    Await 孫Task
                End Sub)
        Finally
          tokenSource.Dispose()
        End Try
        Debug.Print($"FinishTask ID:{CurrentId} スレッド:{CurrentThread.ManagedThreadId}")
    End Sub
    ところが、動かしてみると、どうも子タスクは、孫タスクの終了を待ってくれないようです。Awaitで待機しているにもかかわらず。
    なぜでしょうか?
    StartTask ID: スレッド:1
    子Task ID:1 スレッド:3
    孫子Task ID:3 スレッド:4
    孫TaskCount:0
    子TaskCount:0
      (省略)
    孫TaskCount:4
    子TaskCount:4
    FinishTask ID: スレッド:1
    孫TaskCount:5
    孫TaskCount:6
    一方、ボタン2を押すと見かけ上は、なんとなく動いているようにも見えるような結果が得られましたが、根本的な問題解決になっていないことは理解しています。また、Task.Runでtokenを渡していませんが、現時点では、意図的なものです。
    StartTask ID: スレッド:1
    子Task ID:1 スレッド:3
    孫子Task ID:3 スレッド:4
    子TaskCount:0
    孫TaskCount:0
    孫TaskCount:1
    子TaskCount:1
    子TaskCount:2
    子Taskは、停止しました。
    孫TaskCount:2
    孫Taskは、停止しました。
    FinishTask ID: スレッド:1
    子タスクが、孫タスクを待つようにするには、どのようにすれば良いのでしょうか?
    詳しい方いらっしゃいましたら、御指南頂けないでしょうか?宜しくお願い致します。
    

違反を報告
引用返信

▽[全レス5件(ResNo.1-5 表示)]
■34991 / ResNo.1)  Re[1]: Taskの入れ子の待ち方
□投稿者/ Hongliang 大御所(616回)-(2022/01/06(Thu) 11:29:38)
  • アイコン
    Visual Studio 2019をご使用とのことですが、そうであるなら、
    Await Task.Run(
        Async Sub()
    のAsync Sub()のところに警告を示す波線が引かれていると思います。
    そこにマウスオーバーすれば警告内容がツールチップで表示されます。
    また[エラー一覧]ウィンドウにも同じ内容の警告が出ていると思います。

違反を報告
引用返信
■34992 / ResNo.2)  Re[2]: Taskの入れ子の待ち方
□投稿者/ Wan 付き人(52回)-(2022/01/06(Thu) 14:59:49)
  • アイコンHongliangさんいつもお世話になっております。
    ご指摘通り、Async Function() As Taskに変更しただけで、問題なく動きました。

    でも、どこで、Task(多分?孫Task?)がReturnされるのでしょうか?
    なぜ?Functionなのでしょうか?
    お手を煩わせてすみません。

違反を報告
引用返信
■34993 / ResNo.3)  Re[3]: Taskの入れ子の待ち方
□投稿者/ Hongliang 大御所(617回)-(2022/01/06(Thu) 15:48:17)
  • アイコン
    > でも、どこで、Task(多分?孫Task?)がReturnされるのでしょうか?
    
    Awaitを含むFunctionは、コンパイラが暗黙にTaskを返却するようなコードにコンパイルします。
    Async Function Hoge() As Task
        Debug.WriteLine("enter") ' 一度Awaitするまでは同期的に実行される
        Await Task.Delay(1000) ' Task.Delayおよびそれ以降の処理がTaskとして返値になる
        Debug.WriteLine("exit")
    End Function
    
    > なぜ?Functionなのでしょうか?
    
    Subは返値なし、Functionは返値ありです。
    Sub Hoge() As Taskとは書けません。
    Taskを返したいならFunctionでなければなりません。
    Async Subと書くケースはほぼイベントハンドラのみになるはずで、
    ほとんどの場合Async Functionになります。

違反を報告
引用返信
■34994 / ResNo.4)  Re[4]: Taskの入れ子の待ち方
□投稿者/ Wan 付き人(53回)-(2022/01/06(Thu) 16:18:42)
  • アイコンHongliangさん
    お返事有難うございます。

    Awaitは、メソッド内の実行位置に関わらず、そのメソッドが終了する時に、コンパイラが忖度して呼び出し元にTaskを返すということでしょうか?

    だから、Functionで受け取らないとダメってことですね?

    有難う御座いました。
    また、よろしくお願いします。

違反を報告
引用返信
■34995 / ResNo.5)  Re[5]: Taskの入れ子の待ち方
□投稿者/ Wan 付き人(54回)-(2022/01/06(Thu) 16:19:15)
  • アイコン解決済みです。
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-5]






Mode/  Pass/


- Child Tree -