1

フォーム アプリケーションの開始時に無限 while ループを実行する必要があります。フォームは次のように始まります。

public Form1()
{
        InitializeComponent();
}

ここで、1 秒のスリープ時間で内部に無限ループを持つ別の関数を実行したいと思います。

public void doProcess(){

    while(true){
         Thread.Sleep(1000);
         // other task
    }
}

これどうやってするの?コンストラクターを呼び出すdoProcess()と、フォームが表示されません。while ループを 10 回実行しようとしました。フォームは、すべての反復が終了した後にのみ表示されました。なぜそれが起こっているのかわかりません。

4

6 に答える 6

4

つまり、この無限ループで UI スレッドをブロックしています。

非同期で実行します:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        BeginWork();
    }

    private async void BeginWork()
    {
        while (true)
        {
            // Since we asynchronously wait, the UI thread is not blocked by the file download.
            var result = await DoWork(formTextField.Text);

            // Since we resume on the UI context, we can directly access UI elements.
            formTextField.Text = result;
        }
    }

    private async Task<string> DoWork(object text)
    {
        // Do actual work
        await Task.Delay(1000);
        // Return Actual Result
        return DateTime.Now.Ticks.ToString();
    }
}

while(true) は、更新ループに対して少し過剰になる可能性があります。タイマーを潜在的に使用するか、キャンセル トークンを活用して、高パフォーマンスのシナリオで古い結果で UI を更新しないように時間がかかりすぎたリクエストを積極的にキャンセルすることをお勧めします。

例えば

public partial class Form1 : Form
{
    private readonly Timer _sampleTimer;

    public Form1()
    {
        InitializeComponent();

        _sampleTimer = new Timer
            {
                Interval = 500 // 0.5 Seconds
            };
        _sampleTimer.Tick += DoWorkAndUpdateUIAsync;
    }

    private async void DoWorkAndUpdateUIAsync(object sender, EventArgs e)
    {
        // Since we asynchronously wait, the UI thread is not blocked by "the work".
        var result = await DoWorkAsync();

        // Since we resume on the UI context, we can directly access UI elements.
        resultTextField.Text = result;
    }

    private async Task<string> DoWorkAsync()
    {
        await Task.Delay(1000); // Do actual work sampling usb async (not blocking ui)
        return DateTime.Now.Ticks.ToString(); // Sample Result
    }

    private void startButton_Click(object sender, EventArgs e)
    {
        _sampleTimer.Start();
    }

    private void stopButton_Click(object sender, EventArgs e)
    {
        _sampleTimer.Stop();
    }
}
于 2013-06-17T08:04:06.000 に答える
2

これは、ctor が終了せず、フォームを表示できないために発生しています。これは明白ではありませんか?

これを永久/スリープループ行で実行したい場合は、スレッド化する必要があります。

GUI イベント ハンドラー (または ctors) で待機しないでください。

forms.timer は使えないのですか?

于 2013-06-17T08:03:03.987 に答える
1

UI スレッドをブロックしています。したがって、doProcess実行中は UI を処理できません。

.Net 4.5 を使用している場合は、非同期待機を使用できます。

public async void doProcess(){
    while(true){
         await Task.Delay(1000);
         // other task
    }
}

よりクリーンな解決策は、1 秒ごとにイベントを発生させるタイマーを使用することです。10回ループした後、タイマーをオフにすることができます。

于 2013-06-17T08:04:21.173 に答える
0

Initialize コンポーネントの後に配置するか、フォームの load イベントを見つけてそこにコードを貼り付けることができます

于 2013-06-17T08:12:05.867 に答える
0

コンストラクターを終了しなかったため、フォームは表示されません。フォームが表示された後に実行する場合は、コードを Form_Load イベントに配置します。しかし、backgroundworker を使用できるように、バックグラウンド スレッドを使用して実行したい場合があります。

于 2013-06-17T08:04:49.567 に答える