1

スタートとストップの2つのボタンがあります。開始ボタンをクリックすると、テーブルをヒットしてレコードをループし、レコードがループしている時間の差 (所要時間) を表示したいと思います。

ただし、開始ボタンをクリックすると、レコードの数が多いため、「停止」ボタンをクリックできません。開始ボタンをクリックして、そのプロセスを個別に実行しようとしています。たとえば、5000 レコードが処理された場合、停止ボタンをクリックして、5000 レコードにかかった時間を表示したいのですが、もう一度開始をクリックすると、中断したところからレコードを続行します。

2 つのイベントを個別に処理するにはどうすればよいですか? どんな考えでも本当に役に立ちます。よろしくお願いします。

private void startQueries()
{


thread=

new Thread(this.LoadResults);

thread.IsBackground =true;

thread.Start();

}

private void LoadResults()
{
 //Method that runs a select query - fetches 1000s of records
 Timespan startTime = <<Record the start time>>;

 //Loop thro' all the 1000s of records;

Timespan stopTime=<<Record the stop time>>;

//Display the difference between start and stop time.

}

    private void btnStart_Click(object sender, EventArgs e)
    {

    if(thread!=null)
    {
    if (thread.ThreadState == ThreadState.Running)
    {
    //do nothing
    }
    else if (thread.ThreadState == ThreadState.Suspended)
    {
    startQueries();
    }

    }

private void btnStop_Click(object sender, EventArgs e)
{
  //Stop the running thread

 // Need to display the time between the thread start and stop.
}
}
4

2 に答える 2

0

.NET 4.5 以降を使用している場合は、新しい非同期機能を使用できます。これにより、コードが非同期で発生している場合でも、コードがクリーンでシーケンシャルに見えるフローになります。

public partial class Form1 : Form
{
    CancellationTokenSource _cancellationSource;
    int _currentRecord;
    int _maxRecord;

    public Form1()
    {
        InitializeComponent();
        _currentRecord = 0;
        _maxRecord = 5000;
    }

    private async void btnStart_Click(object sender, EventArgs e)
    {
        await StartQueriesAsync();
    }

    private async Task StartQueriesAsync()
    {
        _cancellationSource = new CancellationTokenSource();
        var sw = new Stopwatch();

        try
        {
            // for Progress<>, include the code that outputs progress to your UI
            var progress = new Progress<int>(x => lblResults.Text = x.ToString());
            sw.Start();
            // kick off an async task to process your records
            await Task.Run(() => LoadResults(_cancellationSource.Token, progress));
        }
        catch (OperationCanceledException)
        {
            // stop button was clicked
        }

        sw.Stop();
        lblResults.Text = string.Format(
            "Elapsed milliseconds: {0}", sw.ElapsedMilliseconds);
    }

    private void LoadResults(CancellationToken ct, IProgress<int> progress)
    {
        while(_currentRecord < _maxRecord)
        {
            // watch for the Stop button getting pressed
            if (ct.IsCancellationRequested)
            {
                ct.ThrowIfCancellationRequested();
            }

            // optionally call this to display current progress
            progress.Report(_currentRecord);

            // simulate the work here
            Thread.Sleep(500);

            _currentRecord++;
        }
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
        _cancellationSource.Cancel();
    }
}

[開始] ボタンをクリックすると、Task.Runを介してタスクが開始され、[停止] ボタンを監視するためのCancellationTokenと、実行時間の長いタスクの動作に合わせて UI を更新するコードを含むProgressオブジェクトが渡されます。

タスクの実行時間を記録するために、タスクの前にStopwatchオブジェクトも作成されます。

また、現在の記録は維持されるため、停止後に再開すると、中断したところから再開されることにも注意してください。

于 2013-07-09T14:08:00.677 に答える