733050 ランダム
 HOME | DIARY | PROFILE 【フォローする】 【ログイン】

【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! --/--
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x
Feb 4, 2021
XML
カテゴリ:備忘録

かなり調べたんだけどスマートなかつ完璧なものは見つからなかったので
作成してみた。
これが、合ってるかわからないけど、思うように動くので参考にしてください。

今回はメインフォームがメインスレッドとします。
OnClassがイベント受け取り
わざと2秒の待機を設置しています。

サブクラスは非同期処理で動きます。
メインスレッドのOnClassに時間を消費してもサブクラスの非同期は待ってくれません。
どんどんイベントを送ってきます。しかし、送られてくる情報は常に変わるため
思った情報が来ない時があります。

これではプログレスバーが飛び飛びのかっちょ悪いものになるでしょう!
そこでイベント発行時の情報を固定して
OnClassに渡す必要があります。
これらもスマートに作るためにカスタム
EventArgを作成します。

非同期スレッドから同期スレッドにイベントを渡す場合
FORMのスレッド情報を非同期スレッドに渡す必要がありました。
渡すのにthisとかを組み込むのがスマートじゃない!

今回は非同期処理のClass側に

SynchronizationContext
を組み込みます。

これは今現在のスレッド情報を変数に入れることができます。

メインスレットの時に実行するとメインスレッドの情報を取得することができるんですね!




---------------------------------------メインスレッド
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace thredtest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Class1 class1;
private void Form1_Load(object sender, EventArgs e)
{
class1 = new Class1();
class1.CountEvent += OnClass;
class1.Start();
}

//private EventHandler OnClass(object sender ,EventArgs e)

private void OnClass(int CountEvent)
{
label1.Text = CountEvent.ToString() ;
Console.WriteLine(CountEvent + "カウント:スレッドID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
//System.Threading.Thread.Sleep(2000);
}

}

}




こっちが非同期Classです。
new Class1を作成したときはまだ、メインクラスで動作しているので
testSync = SynchronizationContext.Current;
はメインクラスの情報が入ります。
ただし、thisと違い変数などを見ることはできません。

重たい処理
Eventset()内に置きましょう
ここではスリープ 1秒させます。
重たい処理1秒が完了したらイベントを発生させます。
処理方法としては

testSync.Post(_ => CountEvent(CountSet) , null);

です。

CountSetはその時の情報を入れてメインスレッドに渡します。
クラスで生成したCountint2 は非同期で+1されていきますので
この情報をそのまま渡しても1,2,3,4,5,6とメインスレッドで受け取れるものでは
ありませんん。
Eventset()内で変数を作成してここにCountint2 の値を入れます。
int CountSet = 0;
その後

testSync.Post(_ => CountEvent(CountSet) , null);

これでメインスレッドに変数を渡すと
メインスレッドの処理が遅くても(今回は2秒の待ち処理を入れても)
渡された変数は1,2,3.4.5.6.7.8.9.10と順番に変化します。
6を渡された時には非同期スレッドは完了してClass1の

class1 = new Class1();
これ自体は消失していますが、10までちゃんとイベントが発生します。


---------------------------------------サブスレッドClass

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace thredtest
{
class Class1
{
public int Countint2 { get; set; }
private readonly SynchronizationContext testSync;
public delegate void CountEventArg(int e);
public event CountEventArg CountEvent;
protected virtual void OnCountEventt(int c) {
CountEvent?.Invoke(c);
}
public Class1()
{
testSync = SynchronizationContext.Current;
Countint2 = 0;
}
public void Start()
{
Console.WriteLine("Class1:スレッドID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
Task.Run(() => {
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Class1:FOR1:スレッドID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
Eventset();
Console.WriteLine("Class1:FOR2:スレッドID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
}
});
Console.WriteLine("Class2:スレッドID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
}

public void Eventset()
{
int CountSet = 0;
Countint2 += 1;
//現在の変数をメインスレッドに送る変数にセットする。
//これでイベント発生時の状態を保持して送ることができる。
CountSet = Countint2;

//サブスレッドで重たい処理
System.Threading.Thread.Sleep(1000);

Console.WriteLine("Class1:Eventset1:スレッドID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);

//メインスレッドにイベントを送る
                if(DataLoad != null)
                    MainThredContrl.Post(_ => DataLoad(NetHttpData),null);

Console.WriteLine("Class1:Eventset2:スレッドID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
}

}

}


すいません、タブがなくなり見にくいですが勘弁してください。






お気に入りの記事を「いいね!」で応援しよう

Last updated  Feb 4, 2021 11:17:44 PM
コメント(7) | コメントを書く


■コメント

お名前
タイトル
メッセージ
画像認証
別の画像を表示
上の画像で表示されている数字を入力して下さい。


利用規約に同意してコメントを
※コメントに関するよくある質問は、こちらをご確認ください。


ツムツム自動周回の件   Y.M さん
記事とは別件で恐縮ですが、以前、ツムツムの自動周回スクリプトを作成されていたかと存じます。
再度販売頂くことは可能でしょうか。

ご相談含め、下記アドレスまでご連絡頂けますと幸いです。

lionking468@icloud.com
※@は半角です

よろしくお願いいたします。 (Feb 5, 2021 08:56:31 AM)

Re:Mainとは別のClass内サブスレッド(非同期処理)からイベントを発行してメインスレット(UI)に情報を送りたい!(02/04)   cocoa0431 さん
こんにちは今利用しているiPhoneに合わせて作り直す必要あります
販売は可能です
機種はなんでしょう? (Feb 5, 2021 06:08:04 PM)

Re[1]:Mainとは別のClass内サブスレッド(非同期処理)からイベントを発行してメインスレット(UI)に情報を送りたい!(02/04)   Y.M さん
cocoa0431さんへ

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

機種はiPhone 7 Plusです。
スクショ等必要でしたら準備いたします。

よろしくお願いいたします。 (Feb 9, 2021 03:19:26 PM)

Re:Mainとは別のClass内サブスレッド(非同期処理)からイベントを発行してメインスレット(UI)に情報を送りたい!(02/04)   KONASI さん
初めまして、AutoTouchのスクリプト作成を
お願いしたいので、可能であれば
折り返し連絡いただきたいです
tatsumi203@gmail.com (Mar 1, 2021 02:01:37 AM)

Re:Mainとは別のClass内サブスレッド(非同期処理)からイベントを発行してメインスレット(UI)に情報を送りたい!(02/04)   もげた さん
以前、星ドラのクエスト周回でお世話になった者です。あの時はありがとうございました。今回もお願いしたい事があり連絡しました。
剣と魔法のログレスでリセマラの周回とリセマラした結果を保存?する方法の2作業を依頼したいです。 (Apr 26, 2021 03:35:58 PM)

Re[1]:Mainとは別のClass内サブスレッド(非同期処理)からイベントを発行してメインスレット(UI)に情報を送りたい!(02/04)   cocoa0431 さん
もげたさんへ
こんにちは、今
 iPhoneのアプリを作成してて時間が取れません
 急ぎですか? (Apr 26, 2021 08:57:47 PM)

Re[6]:Mainとは別のClass内サブスレッド(非同期処理)からイベントを発行してメインスレット(UI)に情報を送りたい!(02/04)   もげた さん
cocoa0431さんへ
こんばんは♪急ぎではないです!お手隙の時にで構いません! (Apr 26, 2021 09:58:49 PM)

PR

Profile

cocoa0431

cocoa0431

Free Space

Comments

Morrisanent@ plaquenil pharmacy &lt;a href=&quot; <small> <a href="http…
Morrisanent@ plaquenil over the counter &lt;a href=&quot; <small> <a href="http…
Morrisanent@ hydroxychloroquine usa &lt;a href=&quot; <small> <a href="http…
Morrisanent@ aralen over the counter <small> <a href="http://hydroxychloroq…
Morrisanent@ where to get chloroquine chloroquine ph 250 mg tablet &lt;a href…

Category

Rakuten Card

Recent Posts


© Rakuten Group, Inc.