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

スレッドプールの一時停止処理

環境/言語:[Win2008Server C# Framework4.0]
分類:[.NET]

環境:VC#2010 Win2008Server

はじめまして。
上記環境にてプログラムを作成しています。

スレッドプールで該当タスクのみ一時停止させたいのですが、
どのようにすれば実現可能でしょうか?
sleepでは先に進んでしまうので困っています。

以下のような電文送信処理をスレッドプールで実装しています。

******************************************************************
send = new WaitCallback(Send);

void Send(object obj)
{
string msg;

TaskABC tabc = (TaskABC)obj;
msg = tabc.strabc;
MSG = msg;
ot = tabc.taskOutou;

for (int i = 1; i <= 3; i++)
{
if (MSG[ot] != "")
{
//電文送信
try
{
serialPort2.WriteLine(msg);
}
catch
{
//送信エラー
}

//2000msec待機して繰り返す
System.Threading.Thread.Sleep(2000);
}
else
{
//再送信の必要がない場合
break;
}
}
}

public class TaskABC
{
//Sendに渡すデータ
public string strabc;
public int taskOutou;

//コンストラクタ
public TaskABC(string st1, int outou)
{
strabc = st1;
taskOutou = outou;
}
}

private void button3_Click(object sender, EventArgs e)
{
TaskABC tabc;
tabc = new TaskABC("DEF", ott);
System.Threading.ThreadPool.QueueUserWorkItem(send, tbac);
ott = ott + 1;
}
*********************************************************************

上記、スレッドプールにて2000msec間隔でデータを送信したいのですが、
うまくいきません。

MSG != ""が成立している場合、
DEF送信 (2秒後) DEF送信 (2秒後) DEF送信
という処理をしたいのですが、
DEF送信 (2秒後) DEF送信×2 (2秒後) DEF送信×3 (2秒後) DEF送信×3 (2秒後) DEF送信×2
となって、合計で11回もDEFが送信されてしまいます。

なお、スレッドプールにしているのは、
DEF送信 (2秒後) DEF送信 (2秒後) DEF送信の処理の間に、
  GHI送信 (2秒後) GHI送信 (2秒後) GHI送信という処理を挟みたいからです。

※MSGは受信スレッドにて返信確認をすると""になります。

よろしくお願いします。
その説明では要領を得ませんが・・・(よくわからん)

要は、シリアル通信で、1個のデバイスに、複数のスレッドが排他制御しつつ、
DEF送信を2秒間隔で行うのとGHI送信を2秒間隔で行いたい。
と言うことですか?

そこまで複雑なことを行うのを、このような掲示板で理解するまでカキコみ
させるのは無理でしょう。プログラムの先生を探しているみたいで、誰も、
そこまで手取り足取り教えてはくれん・・・

まずは、シリアル通信せずに、文字を画面に表示させる機能を、1個のスレ
ッドかバックグランドワーカーで、2秒間隔で動作するものを作ってから、
シリアル通信に転用するとか・・・

そこまでできたら、DEF送信とGHI送信を行う2個の方法にするとか・・・

何はともあれ、プログラミングの技術もさることながら、.NETに用意されて
いるいろいろな機能を知ることも必須かと。

やること沢山あるので、ひとつづつ解決しましょう。

以上。参考まで
オショウさん、ご回答ありがとうございます。

説明下手で申し訳ありません。
オショウさんのご意見を参考に、
まずは画面表示でテストしてみます。

ありがとうございます。
画面表示では思ったとおりの動作になりました。

お恥ずかしい限りですが、
まったく別のところで再送信の処理が走っていたようです。

参考になるか分かりませんが、
ミニマム化した際のコードを置いていきます。
ありがとうございました。

namespace ThreadTest
{
public partial class Form1 : Form
{
public System.Threading.WaitCallback send;
delegate void Writetxt(string strtxt);
System.DateTime dt;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
send = new WaitCallback(Send);
}

void Send(object obj)
{
string msg;

TaskABC tabc = (TaskABC)obj;
msg = tabc.strabc;

for (int i = 1; i <= 3; i++)
{
//電文送信
try
{
dt = DateTime.Now;
BeginInvoke(new Writetxt(TxtWrite), new object[] { dt.ToString("yyyy/MM/dd,HH:mm:ss.ff,") + msg }); ;
}
catch
{
//送信エラー
MessageBox.Show("送信エラー");
}

//2000msec待機して繰り返す
System.Threading.Thread.Sleep(2000);
}
}
}

public class TaskABC
{
//Sendに渡すデータ
public string strabc;

//コンストラクタ
public TaskABC(string st1)
{
strabc = st1;
}
}


private void button1_Click(object sender, EventArgs e)
{
TaskABC tabc;
tabc = new TaskABC("DEF");
System.Threading.ThreadPool.QueueUserWorkItem(send, tabc);
}

private void button3_Click(object sender, EventArgs e)
{
TaskABC tabc;
tabc = new TaskABC("GHI");
System.Threading.ThreadPool.QueueUserWorkItem(send, tabc);
}

private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}

private void TxtWrite(string str)
{
try
{
textBox1.Text = textBox1.Text + str + "\r\n";
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
}
catch
{
MessageBox.Show("書込みエラー");
}
}
}
}

実行結果
2012/09/25,10:32:24.18,DEF
2012/09/25,10:32:25.16,GHI
2012/09/25,10:32:26.20,DEF
2012/09/25,10:32:27.16,GHI
2012/09/25,10:32:28.20,DEF
2012/09/25,10:32:29.16,GHI
解決済み!

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