第23講 BackgroundWorkerによるマルチスレッド
第4話 BackgroundWorkerの練習その3
前話問題解答
#pragma once
long N;
namespace backgroundWorker練習 {
・
・
・
#pragma endregion
String^ w1;String^ w2;String^ w3;String^ w4;
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^
e) {
N=int::Parse(textBox1->Text);
backgroundWorker1->RunWorkerAsync();
backgroundWorker2->RunWorkerAsync();
backgroundWorker3->RunWorkerAsync();
backgroundWorker4->RunWorkerAsync();
}
private: System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
long w=0;
int i;
for(i=1;i<N+1;i++)w+=i;
w1=w.ToString();
}
private: System::Void backgroundWorker1_RunWorkerCompleted(System::Object^ sender, System::ComponentModel::RunWorkerCompletedEventArgs^ e) {
label1->Text = L"1から"+N.ToString()+L"の整数の和";
label5->Text = w1;
}
private: System::Void backgroundWorker2_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
long w=0;
int i;
for(i=2;i<N+1;i+=2)w+=i;
w2=w.ToString();
}
private: System::Void backgroundWorker2_RunWorkerCompleted(System::Object^
sender, System::ComponentModel::RunWorkerCompletedEventArgs^ e) {
label2->Text = L"1から"+N.ToString()+L"の偶数の和";
label6->Text = w2;
}
private: System::Void backgroundWorker3_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
long w=0;
int i;
for(i=1;i<N+1;i+=2)w+=i;
w3=w.ToString();
}
private: System::Void backgroundWorker3_RunWorkerCompleted(System::Object^ sender, System::ComponentModel::RunWorkerCompletedEventArgs^ e) {
label3->Text = L"1から"+N.ToString()+L"の奇数の和";
label7->Text = w3;
}
private: System::Void backgroundWorker4_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
long w=0;
int i;
for(i=1;i<N+1;i++)w+=i*i;
w4=w.ToString();
}
private: System::Void backgroundWorker4_RunWorkerCompleted(System::Object^
sender, System::ComponentModel::RunWorkerCompletedEventArgs^ e) {
label4->Text = L"1から"+N.ToString()+L"の整数の2乗の和";
label8->Text = w4;
}
};
}
それでは皆さん、前に作った素数探索ソフトをBackgroundWorker版で作ってみましょう。
タイムラグの問題は、次のようにすれば、RunWorkerCompletedを使わなくても解決できます。
backgroundWorker1->RunWorkerAsync();
backgroundWorker2->RunWorkerAsync();
backgroundWorker3->RunWorkerAsync();
backgroundWorker4->RunWorkerAsync();
array<String^>^ w=gcnew array<String^>(10);
DateTime^ ow=DateTime::Now; //終了時間
i=0;
while(1){
s.insert(s1[i]);
i++;
if(100<i)break;
}
i=101;
while(1){
s.insert(s1[i]);
i++;
if(cn1<i)break;
}
i=0;
while(1){
s.insert(s2[i]);
i++;
if(100<i)break;
}
i=101;
while(1){
s.insert(s2[i]);
i++;
if(cn2<i)break;
}
i=0;
while(1){
s.insert(s3[i]);
i++;
if(cn3<i)break;
}
i=0;
while(1){
s.insert(s4[i]);
i++;
if(cn4<i)break;
}
while文については後ほどアップしたいと思っていますが、
繰り返し処理の1つです。
基本的な構文は次のようになっています。
while(条件式){
・
・
・
}
条件式が、正しいとき処理を繰り返します。
条件式が偽になったときに処理を中止します。
例えば、
int k=1;
int w=0;
while(w<100){
w+=i;
}
これは
1+2+3+・・・を計算していって、和が100以上になったら計算を止める繰り返し処理です。
for文で書くとすると、
int w=0;
int i;
for(i=0;i<20;i++){
if(w+i<100)
w+=i;
else
break;
}
となるでしょうか。20は勘です。
幾つまで足すと越えるか分からないときは、while文を使った方すっきりします。
尚、条件式が真であることは1に対応します。
w<100が真であるとき、「w<100」という式自体が1の値をもち、
w<100が偽であるとき、「w<100」という式自体が0の値をもっています。
簡単に言うと1が真、0が偽に相当します。
ですから、
while(1){
s.insert(s1[i]);
i++;
if(100<i)break;
}
のような使い方もできます。
この場合は、ループを抜け出す条件を与えないと無限ループしてしまいます。
if(100<i)break;が今回の場合は抜け出すための条件です。
因みに
while(0){
・
・
・
}
だと、1回もループ処理は行われません。
なぜ、これで大丈夫かというと
while(1){
s.insert(s1[i]);
i++;
if(100<i)break;
}
で時間稼ぎをしているのです。
この処理を行っている間にタイムラグが埋められるというわけです。
探索範囲が100未満なら明らかに
while(1){
s.insert(s1[i]);
i++;
if(100<i)break;
}
は無駄打ちです。というのはcn1=5ですから、
i=6からi=99までは無駄打ちです。
この無駄打ちによって時間差を埋めているわけです。
第23講第3話へ 第23講第5話へ
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座