説明と背景: この質問がうまくいかない場合は申し訳ありませんが、タスクについて頭を悩ませようとしています。私は現在、コントロールをコンストラクターに取り込んで、ユーザーの操作 (テキストボックスへの入力、ボタンのクリックなど) を自動化できる一連のクラスを持っています。
これらの 1 つの例は、 と呼ばれる私のクラスTextboxTester
です。テキストボックスをどのように取り込むかのスニペットを次に示します。
public class TextboxTester
{
private int _currentTextLength = 0;
private string _text;
private TextBox _textBox;
private Timer timer;
#region Constructor
public TextboxTester(TextBox TextBox)
{
_textBox = TextBox;
}
#endregion
一連のユーザー入力イベントを自動化できるように、アクション (タスク) を順番に連鎖させたいと考えています。私は TPL タスクについて調べて調べ、試してみることにしました。
TextboxTester
クラスとクラスを作成ButtonTester
し、コントロールを渡しました。テキストボックスに入力してからボタンをクリックできるようにしたいので、これを呼び出します:
Task.Factory.StartNew(() => txtTester.WriteText("Hello World")).Wait();
Task.Factory.StartNew(() => btnTester.Click(1));
Task.Factory 呼び出しに関する私の知識から、これが私がやりたいことです。最初のアクションを実行し、それが完了するまで待ってから、次のアクションを実行します。問題は、タイマーを使用して(1 秒あたり 1 文字)TextboxTester.WriteText()
への入力をエミュレートすることです。TextBox
public void WriteText(string Text)
{
if (timer == null)
{
State.Working = true;
timer = new Timer();
try
{
_text = Text;
timer.Elapsed += new ElapsedEventHandler(timer_ElapsedWrite);
timer.Interval = 1000;
timer.Enabled = true;
timer.Start();
}
catch
{
MessageBox.Show("WriteText timer could not be started.");
}
}
}
void timer_ElapsedWrite(object sender, ElapsedEventArgs e)
{
_textBox.Dispatcher.BeginInvoke(new Action(() =>
{
TextBoxAutomationPeer peer = new TextBoxAutomationPeer(_textBox);
IValueProvider valueProvider = peer.GetPattern(PatternInterface.Value) as IValueProvider;
valueProvider.SetValue(_text.Substring(0, _currentTextLength));
if (_currentTextLength == _text.Length)
{
timer.Stop();
State.Working = false;
timer = null;
return;
}
_currentTextLength++;
}));
}
**_textBox.Dispatcher
経過イベントでの呼び出しは、発生していた「スレッドは既にこのオブジェクトを所有しています」というメッセージを防ぐためのものでした。
最後に問題: Task.Factory.StartNew() 呼び出しは、まだ発生している time_elapsed イベントを考慮していないようです。タスクが「WriteText」が完了したと見なす前に、イベントを終了できるようにしたいと考えています。
質問: これらの種類のことを考慮に入れることができるようにタスクに指示する方法はありますか? タスクを理解していませんか?
編集 - TPL の 3.5 および 3.5 実装を使用しています