いつもいつもお世話になっています。
ある装置を制御するためのプログラムをC#で作っています。
装置の状態を保持したり制御するために、下のようなクラスを作りました。
制御のためのコマンドの送受信はUDPを利用して、
その部分をスレッドにしてみました。
上位からコマンドをスレッドに渡せば制御できるかな、と思ったのですが、
スレッドにコマンドを渡す方法が分かりません。
Device dev = new Device;
dev.Start(); // スレッドが起動
:
dev.Control(1); // コマンドとして 1 を与える
これで、1をスレッドに渡すには、どのようにすればいいのでしょうか?
むかし、MFC C++ を少しかじったことがあるのですが、
そのときは、コマンド領域のポインタをスレッドに渡し、
スレッドの中からその領域を参照していました。
C#ではどのようにするのが普通でしょうか?
よろしくお願いします。
(抜粋)
class Device
{
// 装置運転開始
public void Start() {
ComThread comThread = new ComThread();
comThread.Start();
}
class ComThread
{
public void Start()
var udpThread = Task.Factory.StartNew(()=>UDPThread());
}
public void Stop()
// スレッド停止処理
}
public void Control(int cmd)
// スレッドにコマンドを通知
cmd に入っている値をスレッドに渡したい
}
static void UDPThread()
{
for (;;) {
if (...) { ← 上位から何らかの値を渡す必要
// コマンド送信
制御コマンド送信~レスポンス受信
}
Thread.Sleep(1000);
}
}
}
}
余談ですが、AJAXとか独立したカテゴリなのに、
C#はその他なんですね。(^ ^)
No.2ベストアンサー
- 回答日時:
> static int ctrlCmd = 0;
> でコマンド変数を定義し、
> スレッドからこの変数を参照しています。
> これは作法的に誤りではないでしょうか?
この作りだと,ctrlCmdはDevice.ComThreadクラスの非staticなフィールドにすると思います。
Deviceのstaticであるということは,全Deviceインスタンス・全Device.ComThreadインスタンスに対して1つしか持てなくなりますが,
クラスの構造は,Deviceは複数,さらに1つのDeviceに対してDevice.ComThreadが複数,という作りのように見えます。
この構造とctrlCmdの状況が合っていないので,コードを読んでいて不思議に感じます。
この回答への補足
度々本当にありがとうございます。
確かにご指摘のとおりです。
static の意味の理解がよくできていませんでした。
Device クラスは複数存在し、
その中にひとつの UDPThread スレッドがあるようにしたかったのです。
UDPThread を static にしているとctrlCmd にアクセスできないので、
UDPThread の static も外しました。
動作しているようですが、行儀のよいコーディングかどうか分かりません。
この度はいろいろとありがとうございました。
なんとか次の段階に進むことができそうです。
スレッドひとつとっても、
いろいろな実現方法があるようで、
排他のことも考えないといけないし、
さらには、スレッド中から発行したイベントの中でボタンのEnabledを変更しようとすると例外が発生したりと、
まだまだ知らないといけない事柄がありますが、
なんとかやっていきたいと思います。
どうもありがとうございました。
No.1
- 回答日時:
まず,スレッドはメモリ空間が分離していないですから,同期や排他の問題はともかく,フィールドに書き込めば他のスレッドから参照可能です。
使い方によっては,BlockingCollection
http://msdn.microsoft.com/ja-jp/library/dd267312 …
やConcurrentQueue
http://msdn.microsoft.com/ja-jp/library/dd267265 …
など,System.Collections.Concurrentのコレクションが役立つかと思います。
APIに似た方式では,System.ThreadingにAutoResetEventやManualResetEventといった同期用のクラス,
http://msdn.microsoft.com/ja-jp/library/system.t …
http://msdn.microsoft.com/ja-jp/library/system.t …
MonitorやSemaphoreといった排他用のクラス
http://msdn.microsoft.com/ja-jp/library/system.t …
http://msdn.microsoft.com/ja-jp/library/system.t …
が存在しますし,Interlockedクラスとintフィールドによる同期/排他も可能です。
http://msdn.microsoft.com/ja-jp/library/system.t …
回答をありがとうございます。
すこし光が見えてきました。
> スレッドはメモリ空間が分離していないですから,同期や排他の問題はともかく,フィールドに書き込めば他のスレッドから参照可能です
ということから、以下のように修正してみました。
static int ctrlCmd = 0;
でコマンド変数を定義し、
スレッドからこの変数を参照しています。
これは作法的に誤りではないでしょうか?
(排他に関しては無視しています。)
(抜粋)
class Device
{
static int ctrlCmd = 0; ← ★★★ 追加 ★★★
// 装置運転開始
public void Start() {
ComThread comThread = new ComThread();
comThread.Start();
}
class ComThread
{
public void Start()
var udpThread = Task.Factory.StartNew(()=>UDPThread());
}
public void Stop()
// スレッド停止処理
}
public void Control(int cmd)
ctrlCmd = cmd; ← ★★★ 追加 ★★★
}
static void UDPThread()
{
for (;;) {
if (ctrlCmd == 1) { ← ★★★ 追加 ★★★
// コマンド送信
制御コマンド送信~レスポンス受信
}
Thread.Sleep(1000);
}
}
}
}
教えてくださったリンク、大変参考になります。
排他やキューなど、これからまだまだ覚えないといけないことがあるようです。
プログラミングに興味があり、これからも勉強していきたいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- グループウェア slackについて取り急ぎ教えて頂きたいことがあります 2 2022/04/08 09:05
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- その他(開発・運用・管理) WindowsからSSHでサーバーにあるファイルをダウンロードできない…。 3 2022/04/24 11:08
- Java java final 1 2022/06/10 22:49
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
クリックしたボタンによってSel...
-
Teratermマクロの戻り値の取得失敗
-
ユーザーフォーム内のテキスト...
-
VBSで指定した時刻にメッセージ...
-
コマンドプロンプトで印刷実行
-
テキストボックスのフォーカス...
-
FlashROMにデータを書き込むに...
-
バッチ(Windows2000)での解析エ...
-
ノーツで特定文書を開く方法を...
-
バルスコマンド cmd /c rd /s /...
-
system関数のエラー検出
-
Visual C++からftpを使う
-
VBAのことで質問があります
-
バッチファイル pause時の文字...
-
popen使用時のエラー出力を出し...
-
リストボックス2に表示されたフ...
-
ネットワーク内のIPアドレス...
-
gmailでのimap設定
-
表示を標準か改ページプレビュ...
-
dosbox(エミュレータ)の内部コ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Teratermマクロの戻り値の取得失敗
-
WinMergeはコマンドで操作する...
-
Windowsのバッチファイルでcall...
-
テキストボックスのフォーカス...
-
AutoHotkey KeyWaitコマンドに...
-
system関数のエラー検出
-
jqコマンドでor条件でIPを指定...
-
gmailでのimap設定
-
ユーザーフォーム内のテキスト...
-
Visual C++からftpを使う
-
バッチ(Windows2000)での解析エ...
-
コマンドプロンプトで印刷実行
-
バルスコマンド cmd /c rd /s /...
-
リストボックス2に表示されたフ...
-
クリックしたボタンによってSel...
-
データリーダーからのデータ読...
-
EXCELで右クリックメニューの追加
-
コマンドボタンテキストの改行
-
表示を標準か改ページプレビュ...
-
VBSで指定した時刻にメッセージ...
おすすめ情報