サクラエディタ_トピックツリー

間違えて押して偶然知った。

 

F11 で立ち上がる。
アウトライン解析」という機能。

 編集中のテキストから、特定の見出し記号や、関数位置などを解析して
一覧表示する。
ソースコードの関数や宣言を抽出し管理する為のもの。

 

ex)
f:id:koshinRan:20190614134420p:plain

 

 

 

こちらから。
https://sakura-editor.github.io/help/HLP000064.html
https://ncode.syosetu.com/n2989eb/5/

以上。

 

英語_肯定文の疑問文

口語的な表現。きちっとした文章では見られない。
内容確認をしたい時のみ使える。
目の前に起きた状況や、誰かが話していた内容を前提として、
内容確認」をしたい場合に「肯定文の形のまま」で尋ねることが可能。

ex ) She is your mother ?

 

すぐに信じることができなかったり、予想外だった時など
驚きの感情と共に尋ねることができる。

Is ~ などの疑問文は、yes か no のどちらなのか本当に分からない、
という場合に使われる。

 

否定文も同じ。
既に話された内容について内容の確認をしたい場合は、
その内容が「否定」ならば「否定文の形のまま」で尋ねることができる。

 

 

 

こちらから。
http://dupler.co.jp/eng_school/natural_english/question_form/

以上。

C#_メディアプレイヤー ( デザインに配置 )

C# でメディアプレイヤーをつくりたい。再生・終了箇所を指定して繰り返し聞きたかった。

 

ソリューションプラットフォームは Any CPU
f:id:koshinRan:20190511055003p:plain

 

 手順

  1.  [ ツール ] > [ ツールボックス アイテムの選択 ]
  2. [ COM コンポーネント ] タブをクリック。
  3. Windows Media Player にチェックを入れて OK。
    f:id:koshinRan:20190511054950p:plain
  4. デザインのツールボックスWindows Media Player が出現。
  5. デザインビューのフォームに配置する。

 

 

デザインに配置できなかった

ソリューションプラットフォームは Any CPU でなければ配置できなかった。

COM コンポーネントから Windows Media Player にチェックを入れて、
OK をクリックしたら以下のメッセージが。

次のコントロールツールボックスへ正常に追加されましたが、
アクティブなデザイナーで有効になっていません。

 

無視してツールボックスからフォームに貼り付けようとしたら
以下のメッセージが表示された。

コンポーネント 'AxHost' を生成できませんでした。
System.Reflection.ReflectionTypeLoadException:
要求された型のうち 1 つまたは複数を読み込めませんでした。詳細については、
LoaderExceptions プロパティを取得してください。
場所 System.Windows.Forms.Design.DocumentDesigner.AxToolboxItem. ~
場所 System.Drawing.Design.ToolboxItem.CreateComponentsCore ~
場所 System.Drawing.Design.ToolboxItem.CreateComponents ~
場所 System.Windows.Forms.Design.OleDragDropHandler. ~

 

プロジェクトは Windows フォームアプリケーション。
WPF アプリケーションで作成していないWPF はよく分からない。
WPFアプリケーションだと「ActiveX  コントロールをホスト」が必要になるらしい。

 

1 .
新たにプロジェクトを作成、
ソリューションプラットフォームは Any CPU のまま → 成功

WMPLib の「相互運用型の埋め込み」はそのまま。( true )
ここから ソリューションプラットフォーム を x64 に変更しても配置できる。

AxWindowsMediaPlayer の導入により WMPLib が参照に追加されると、
以下のような通知がされることがあるらしい。
  COM 参照 'WMPLib' は ActiveX コントロール 'AxWMPLib' の相互運用アセンブリですが、
  コンパイラによって /link フラグでリンクされるように設定されています。
  この COM 参照は参照として処理され、リンクされません。
これは、WMPLib のプロパティで [相互運用型の埋め込み] を false とすることで解決できる。

とあったので。

 

2 .
新たにプロジェクトを作成、
ソリューションプラットフォーム x64で実行してから配置 → 失敗

WMPLib の「相互運用型の埋め込み」を false にしても失敗。
Any CPU に戻しても配置できない。

 

f:id:koshinRan:20190511090402p:plain

 

 

x64 でエラーが出る原因

Windows フォームデザイナは 32bit で動く。
64bit でしか読み込めないようなライブラリ・アセンブリは貼り付けると
デザイナが表示できなくなるのが原因なもよう。

 

https://social.msdn.microsoft.com/Forums/ja-JP/7a071803-641e-4c09-8821-162e37313539/c12391activex124342035129992123771242712392124561252112540123951?forum=csharpgeneralja より。

まず、.NET の Windows フォームデザイナは 32bit で動きますので、
64bit でしか読み込めないようなライブラリ・アセンブリは貼り付けると
デザイナが表示できなくなります。
( devenv.exe 自体が 32bit であり、そのプロセス内にコンポーネント
を読み込む必要があるため )


たとえば、
ユーザーコントロールを作ってそれを含むプロジェクトが Any CPU ではなく、
x64 指定になっていると、デザイナで表示できません。
この場合、Any CPU として作り、デザイナでは 32bit、実行時は 64bit として
動作させるようにアセンブリを作らないといけません。

その性質を理解した上で構成をうまく作る必要があります。
私が示した例ではユーザーコントロールを含むプロジェクトを exe とは別に作り、
Any CPU にするといった手が考えられます。


次に、ActiveX などの COM コンポーネント .NET 上から使うためには、
相互運用アセンブリと呼ばれる COM の型をラップした .NET 型を含む
アセンブリが必要になります。
これはプラットフォームに依存する形となっており、
x86/x64 で別のアセンブリが生成されたはずです。
また、Visual StudioGUI からは構成 ( プラットフォーム ) ごとに参照する
アセンブリを切り換える機能は有していません。


これらのことから、64bit 向けのアプリとして作り込んで、
デザイナで表示するというのはかんたんにいかないのは確かだと思います。

  

 

 Windows Media Player をフォームに配置せずに再生できる

ユーザーインターフェイス必要なければフォームに配置する必要もない
button コントロールなど配置し、そのイベントハンドラで再生コードを書く。

 

だが、wmp.dll WMPLib.dll参照に追加する必要はある
フォームに Windows Media Player を一度配置すれば、
これらは自動的に追加される。

 

 

 

MediaPlayer クラスメモ

MediaPlayer クラスの説明が検索にかかって混乱した。

WPF におけるマルチメディア関係のクラス。
MediaElement クラスと MediaPlayer クラスがある。

MediaPlayer クラスは Windows Media PlayerWPF で使えるようにした、
いわゆるラップクラス。

MediaElement クラスは MediaPlayer クラスのサブクラスのようなもの。

基本的な機能に違いがあるわけではないが、
MediaElement クラスのほうは XAML コードで使うことを想定し、
MediaPlayer クラスは分離コードを使って操作することを前提としている。

 

 

 

 

こちらから。
http://www.gan.st/gan/blog/index.php?itemid=1406
https://social.msdn.microsoft.com/Forums/aspnet/ja-JP/4273b9f0-e561-4996-9978-9a19cc64a83e/windows-media-player?forum=wpfja
チュートリアル: WPF での ActiveX コントロールのホスト | Microsoft Docs https://teratail.com/questions/38031
AxWindowsMediaPlayer | C# プログラミング解説
https://dobon.net/vb/dotnet/programing/playmidifile.html
http://www.kanazawa-net.ne.jp/~pmansato/wpf/wpf_ctrl_multimedia.htm

以上。

---Memo---
System.Drawing を使うとき。
1.ソリューションエクスプローラーのプロジェクト名を右クリック。
2.[ 追加 ] > [ 参照 ] > 左メニューの アセブリをクリック。
3.System.Drawing にチェックを入れる。

C#_戻り値 void と Task と Task<T>

C#_Invoke と lock と await の続き。

Task<T> を使うなら、await で処理終わってないと使えない。

スレッド → メインスレッド
スレッド → ワーカースレッド
後者が正式名称。

 

async / await の戻り値

async を付けた非同期メソッドの戻り値は、
voidTask Task<T>ValueTask<T> もあるがあまり使われてないもよう。

戻り値が void 以外の時は
メソッド名の最後を Async TaskAsync にすることが推奨。

UI イベント ( button1_Click など ) のメソッド名称は変更不要。 

 

戻り値のパターンにより以下の違いが出てくる。
・メソッド内で return を書く必要の有無。
・タスク内の処理状況 ( 非同期メソッド ) の把握が可能、不可能。
・メソッド名の名称変更が必要、不必要。( 末尾を Async か TaskAsync )

 

 

void を使うパターン

呼び出し側が非同期メソッドの完了を待機する必要ない場合。
return 必要なし、処理状況の把握不可、メソッド名変更不要
void は、UIイベントメソッド ( button1_Clickなど ) でしか使ってはいけない。
イベントメソッドに async を付けた非同期メソッドに限り、void が許される。

void では、非同期メソッドの処理状況情報を
「非同期メソッド」を実行した側が知ることが不可。
Task の完了もされず、例外も知ることができない。 

なお、
await Task.Run( () => {}); と、ラムダ式に書けば、async を付けなくとも書ける。

 

 

Task を使うパターン 

非同期メソッドの完了待機したい場合。
return 必要なし、処理状況の把握可能、メソッド名要変更
特に「戻り値」が必要ない場合に使用する。

ex )
戻り値のない自作のメソッドを非同期メソッドにする場合に Task を使用。

    private void buttonT_Click(object sender, EventArgs e)
    {
        var task = BarAsync();
       
        // なんかの処理 A 。ここの処理は BarAsync と並列。
        //   Task.Run だから別スレッド、なので並列。
        //   メインをここで使っているので UI は動かず。
       
        await task;
       
        // なんかの処理 C 。Foo が完了したら走る。
    }
   
    private async Task BarAsync()
    {
        // Foo() を別スレッドで実行 //Task.Run<string>( () => { と同じ
        Task<string> task = Task.Run<string>(new Func<string>(Foo));
       
        var get = await task;

        // なんかの処理 B 。task が終わってから処理
    }
   
    private string Foo()
    {
        for (int i=0;i<10001;i++)
        {
            Console.WriteLine("F");
        }
        return "End!!!F";
    }

memo
処理の長さを「 Foo = 処理 B < 処理 A 」として実行したが、
Foo と 処理 A は 並列。処理 A が終わってから 処理 B が実行された。
処理 A を中断して処理 B 実行というわけではない。キューに登録された云々が関係しているのか ?

 

 

Task<T> を使うパターン

非同期メソッドから戻り値受ける場合。

return 必要、処理状況の把握可能、メソッド名要変更
戻り値のある自作メソッドを「非同期メソッド」にする場合は、
必ず Task<T> 型の戻り値にする。

Task<T>.Result を使い、受け取った戻り値を取り出す
awati で子スレッドの処理待つこと。
( Task<T>.Result には Task.Wait() 処理が内包されているため )

    private async void buttonT_Click(object sender, EventArgs e)
    {
        var task = await BarAsync();
        // なんかの処理 A
        Console.WriteLine(task + "AllEnd");
    }
   
    private async Task<T> BarAsync()
    {
        // Foo() を別スレッドで実行
        var task = Task.Run<string>(new Func<string>(Foo)); //var は Task<string> 型。
        var get = await task;
        return get; //get は string 型。Task<string> 型は NG
       
        // 以下のようにも書ける。
        //var task = await Task.Run<string>(new Func<string>(Foo));
        //return task ;
    }
   
    private string Foo()
    {
        for (int i=0;i<10001;i++)
        {
            Console.WriteLine("F");
        }
        return "End!!!F";
    }

Foo 、処理 A が終わったら、 End!!FAllEnd と出力される。

 

 

 

こちらから。
http://1studying.blogspot.com/2017/04/c.html
http://1studying.blogspot.com/2017/04/c_22.html
https://blog.xin9le.net/entry/2012/07/30/123150
https://blog.xin9le.net/archive/category/Async

以上。

C#_Invoke と lock と await

再度調べ。UI は親スレッドのみでしか動かない。

 

Invoke

Task により、子スレッドが実行されたとする。
子スレッドから、親スレッドのコントロール ( Form など )データ
書き換える際、Invoke が使われる。 Form 配下の全てのコントロールで使用可。
※複数のスレッド間ではデータのやりとりが制限されている為、
この方法が使われる。( スレッドセーフな呼び出し )

 

Invoke子スレッド内から
親スレッドのコントロールに対して、処理を間借りさせてもらい
親スレッドのコントロール側の内部コードを実行させるメソッド。

親スレッドで実行させたいコード
子スレッド内の Invoke 引数として、デリゲートを使い記述する。

 

ex)

    private void Foo(int i)
    {
        if (label.IsDisposed) return;

        if (label.InvokeRequired)
        {
            //this.Invoke 。Form の Invoke
            Invoke( (MethodInvoker)delegate { Foo(i); } );
        }
        else 
        {
            label.Text = i.ToString();
        }
    }
   
    // 略
    Task.Run(() =>{
   
        // for で 10,000 回など
        Foo(i);
    }

つまり、
Invoke メソッドの引数に渡させた関数 ( デリゲート ) が、親スレッドで実行される
という認識。でいいのか。
違う。子スレッド内で親スレッドの処理だ。?

 

戻り値

Invoke戻り値object
Invoke で親スレッドの処理を行った際の戻り値を使用すれば、子スレッド側から
親スレッドの情報 ( label etc ) のプロパティ値などが取得できる。
return (object)xxxx; と書く。

Task 内の処理が子スレッドで実行中、親スレッド Form は Task が記述された
次の行へすぐ処理を移す。
子スレッドで行う予定の全処理を Task 内にまとめる必要があるが、
async / await を使うと全処理を Task 内にまとめなくともよくなる。

 

 

lock

label への表示が、
ボタン 2 回押したとき「0 1 2 3 4」「0 1 2 3 4」ではなく
「0 1 0 2 1 3 2 4 3 4」と表示される。( Sleep を Foo(i) の次に記述して確認するとこうなる )
これは、子スレッド並列的に処理される為。

lock
1 回目のクリックで子スレッドが実行中の間、
2 回目以降のクリックによる子スレッドの動作を順番待ちにさせておく

    object obj = new object(); // lock 用オブジェクト
   
    private void buttonTest_Click(object ~
       
        Task.Run(() =>{
       
            lock (obj)
            {
                Foo(i);
            }
        }

※ lock 内に await は使えない。await の内に lock も使えない。
await の中のロックは semaphoreSlim を使う。

 

 

async / await 

子スレッドが Task 内の処理を行っている間、親スレッドの Form 側は
Task が記述された次の行へ、すぐに処理を移す。Task 内の処理終了は待たない

await を使うことにより、
親スレッドのForm の動作自体は止めないまま、Task 内処理終了するまで
await が記述された次の行への処理待機させる事が出来る。
Foo () のような書き方をせずに済む。
( 上記は親スレッドと子スレッドから、同じようにコントロールへアクセスする方法。Fooが必要だった )

 

async 修飾子が付いたメソッドを非同期メソッドと呼ぶ。
await を一つ以上使用している、というマーク

 

private async void buttonTest_Click () 内のコード

    for (int i = 0; i < 1001; i++)
    {
        label1.Text = i.ToString();
       
        await Task.Run(()=>{
            System.Threading.Thread.Sleep(1000);
        });
       
        // 以下の書き方も可
        // var task = Task.Run(()=>{ 略 });
        // 処理 A Task.Run を無視して並列的に処理される。
        // 処理 B
        // await task; // Task の処理完了まで待機
        // この行から処理再開
    }

await の Task ( 子スレッド ) で処理が行われている間、Form の動作は止まらず、
await の次の行への処理は行われずに待機
Task 内の処理が終われば await の行から処理再開
Sleep がないと、Invoke で書いたように 0 ~ 1000 まで連続で表示されない。

 

 

 

こちらから。
http://1studying.blogspot.com/2017/04/c.html

以上。

C#_非同期処理の種類

タスク並列 が async/await の記述に関係あるかなと思って流し読みしたがあんま関係なかった。

非同期処理といっても、
いくつかの種類があり書き方・使うライブラリが違う。

バックグラウンド処理 ( 非同期メソッド ( async / await キーワード )  )

並列計算
  ┣データ並列 ( Parallel クラス・並列 LINQ )
  ┗タスク並列 ( TPL Dataflow ライブラリ )

バックグラウンド処理:await や async を使っての記述。
データ並列:Parallel クラス・ParallelEnumerable クラスを利用。
タスク並列/非同期データフロー:TPL Dataflow ライブラリを利用。
上記いずれも、内部的には Task クラスを利用している。

 

バックグラウンド処理 ( 非同期メソッド )

負荷の高い計算や、I/O待ちなどによって CPU やスレッド資源を
保持し続けないために、別スレッドでの計算I/O待ちを行う。

バックグラウンド処理:メイン スレッド以外で行う処理のこと。
( awaitasync を使って記述。←バックグラウンド処理を簡略化するもの )

 

並列計算

マルチコア CPU の性能を最大限引き出すために、同じ計算を複数のコアで
同時に実行。

1) データ並列同じ処理異なるデータに対して繰り返し行う。

2) タスク並列/非同期データフロー ( TPL Dataflowライブラリ )
異なる処理が独立して動いていて、
その間で非同期データのやり取り ( 非同期データフロー ) を行う。

 

 

並列処理

並列処理も非同期処理の一種。マルチコア CPU の性能を最大限引き出す。

1 ) Parallel や AsParallel を使う。 ( データ並列 )

2 )異なる処理 ( タスク ) を独立して動かして、その間で非同期に
データのやり取りする方法。( タスク並列 )

 

2 ) について

memo程度。
異なるタスク並列に動かすという意味では、タスク並列
非同期なデータ受け渡しという意味では、非同期データフロー
と呼ばれている。

※ タスクを動かす、というよりは各々が主体になって独立して動いている
という見方をして、各タスクをアクター ( actor:動作主体、当事者 )
エージェント ( agent: ( 裁量を持って動く ) 職員、代理人 ) と呼ぶこともある。

 

非同期データフローを実現するためのライブラリが TPL Dataflow。
TPL:Task Pallalel Library。Task クラスや Parallel クラスの総称。
TPL Dataflow は、.NET Framework 本体とは独立したリリース サイクルで
提供されている。NuGet を通して使うことができる。

非同期データフローを実現するために必要なのは、
データ受け渡しを仲介して、データをイベント駆動的に受け取れるバッファー。?
( イベントが発生したらデータを受け取る、という意味 ? )

 

TPL DataFlow が提供しているのは、このようなバッファーを持った動作主体。
 ( DataFlow ライブラリの場合、ブロックと呼ばれている )
ex ) 提供例
ISourceBlock:データを送ってくる元のブロックを表す。
ITargetBlock:データを送る先のブロックを表す。
JoinBlock:複数のブロックから来た値を 1 つにまとめる。

駆動:動力を与えて動かすこと。

イベント駆動型プログラミング
マウスをクリックや、キーボード押下など、
何か特定のことが起こったら ( イベントが発生したら ) 処理を実行するように
プログラムすること。

 

 

 

こちらから。
https://ufcpp.net/study/csharp/AsyncVariation.html
https://www.atmarkit.co.jp/ait/articles/1109/30/news126.html
https://wa3.i-3-i.info/word13776.html
https://www.otsuka-shokai.co.jp/words/event-driven-type-programming.html

以上。

C#_非同期メソッド

スレッドを使った非同期処理を行いたい動機。

ブロッキング処理
I/O 待ちとかで UI スレッドフリーズさせないようにする。

並列処理
マルチコアを活かした並列処理でパフォーマンス向上

ブロッキング処理 async / await で簡素化。( Ver4.0 前はとてもメンドイ書き方 )
並列処理は、Parallel クラスや Parallel LINQ で簡単に対応可能。

 

非同期であっても、必ずしもマルチスレッドで実行されるわけではない
async/await が Task クラスの上に成り立っているため、
可能な限り同じスレッドを使いまわそうとする。Task.Run() なら別スレッド

 

 

非同期メソッドの戻り値の型

void・TaskTask<T> のいずれか。

まず、最終的に Task.Wait () で完了待ちする必要があるか否かで戻り値の型を選ぶ。
待つ必要があるなら Task または Task<T> に、必要なければ void 。

 

非同期でないメソッドから、戻り値が Task 型の非同期メソッドの完了を
待つ RunAsync() は、static async Task RunAsync() {  } 。

    var task = RunAsync();
   
    // 何かの処理。RunAsync と同時進行。
   
    task.wait();

ソースMemo。
RunAsync 関数の中に await Hoge 処理 あり。awati まで処理がきたらvar = task にリターンされ、
Hoge と何かの処理が走る。そして task.wait で RunAsync の処理が終わるまで待つ。

 

完了待ちが必要ない ( 戻り値が void )
GUI アプリケーションのイベント ハンドラーなどで利用。

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        await Task.Run(()=>{ 略 });

 

 

 

こちらから。
https://ufcpp.net/study/csharp/sp5_async.html
https://ufcpp.net/study/csharp/sp5_awaitable.html

以上。