web-dev-qa-db-ja.com

特定の時間間隔の後にメソッドを実行するにはどうすればよいですか?

それは明らかです。たとえば、私のフォームのボタンを想像してみてください。ユーザーがボタンをクリックすると、一部のvoidメソッドが30秒後に実行されます。

2つの入力パラメーターを取るvoidメソッドDoAfterDelayがあります。 1つ目は(デリゲートを使用して)実行する方法で、もう1つは時間間隔です。だから私は持っています:

public delegate void IVoidDelegate();
static void DoAfterDelay(IVoidDelegate TheMethod, TimeSpan Interval)
    {
        // *** Some code that will pause the process for "Interval".
        TheMethod();
    }

したがって、特定の時間間隔でプロセスを一時停止するコードが必要です。これまでは、このコードを使用してそれを行っていました。

System.Threading.Thread.Sleep(Interval);

しかし、このコードはプロセス全体を停止し、プログラムをフリーズさせるため、私にはよくありません。プログラムがDoAfterDelayメソッドで動かなくなることを望まない。そのため、Thread.Sleepは役に立たない。

だから誰もがより良い方法を提案できますか?もちろん私はそれについて検索しましたが、私が見つけたほとんどの解決策はタイマーの使用に基づいていました(たとえば here など)。ただし、メソッドを1回実行する必要があり、タイマーを使用するとプログラムが読みにくくなるため、タイマーを使用することは私の最後の意見です。だから私はもしあればもっと良い解決策を探しています。それともタイマーを使用する必要があるのでしょうか?

私はスレッドで遊ぶ必要があると思いますが、確かではありません。だから、誰かが私を解決策に導くことができるかどうか疑問に思います。前もって感謝します。

15
Mostafa Farzán

タスクを使用できますか?

    Task.Factory.StartNew(() =>
    {
        System.Threading.Thread.Sleep(Interval);
        TheMethod();
    });
14

これは、.Net 4.5の非同期待機機能を使用できる場所です。

Task.Delayを使用して、ミリ秒単位の遅延を与えることができます。これは非常にクリーンな方法です。例:

    private async void button1_Click(object sender, EventArgs e)
    {
        await Task.Delay(5000);

        TheMethod();
    }
13
Jimmy Hannon

Coroutineを作成する必要があります

public IEnumerator waitAndRun()
{
    // WAIT FOR 3 SEC
    yield return new WaitForSeconds(3);
    // RUN YOUR CODE HERE ...
}

そしてそれを次のように呼び出します:

StartCoroutine(waitAndRun());
0
David

を使用して正確な秒を指定できます

DateTime runTime = new DateTime();
double waitSeconds = (runTime - DateTime.Now).TotalSeconds;

Task.Factory.StartNew(() =>
{
    Thread.Sleep(TimeSpan.FromSeconds(waitSeconds));
    YourMethod();
});

runTime =>メソッドを実行する場合。

0
Amey Vartak

ここにあなたが欲しいものがあります:

    public static void Example1c()
    {
        Action action = DoSomethingCool;
        TimeSpan span = new TimeSpan(0, 0, 0, 5);

        ThreadStart start = delegate { RunAfterTimespan(action, span); };
        Thread t4 = new Thread(start);
        t4.Start();

        MessageBox.Show("Thread has been launched");
    }
    public static void RunAfterTimespan(Action action, TimeSpan span)
    {
        Thread.Sleep(span);
        action();
    }
    private static void DoSomethingCool()
    {
        MessageBox.Show("I'm doing something cool");
    }

Actionを使用する利点の1つは、パラメーターを渡すように簡単に変更できることです。 DoSomethingCoolに整数を渡すことができるようにしたいとします。このように変更するだけです:

    public static void Example1c()
    {
        Action<int> action = DoSomethingCool;
        TimeSpan span = new TimeSpan(0, 0, 0, 5);
        int number = 10;

        ThreadStart start = delegate { RunAfterTimespan(action, span, number); };
        Thread t4 = new Thread(start);
        t4.Start();

        MessageBox.Show("Thread has been launched");
    }
    public static void RunAfterTimespan(Action<int> action, TimeSpan span, int number)
    {
        Thread.Sleep(span);
        action(number);
    }
    private static void DoSomethingCool(int number)
    {
        MessageBox.Show("I'm doing something cool");
    }

非常に柔軟...

スレッドを作成するにはいくつかの方法がありますが、もちろん、それはあなたが何をしているかに依存します。次のようにその場でスレッドを作成できます。

Thread aNewThread = new Thread(
    () => OnGoingFunction()
);
aNewThread.Start();

このスレッドはバックグラウンドで実行されます。実行する関数には、処理が完了したときにスリープするsleepメソッドが必要です。だからこのようなもの:

private void OnGoingFunction()
{
   //Code....
   Thread.Sleep(100); //100 ms, this is in the thead so it will not stop your winForm
   //More code....
}

お役に立てば幸いです。

別のオプションは、スレッドを処理する必要があるときはいつでもスレッドを作成し、スリープオプションを気にしないことです。プロセスをロードするたびに新しいスレッドを作成するだけです

0

DoAfterDelayは、1回だけ実行されるタイマーを開始します。タイマーが期限切れになると、void 'TheMethod'関数が呼び出されます。なぜこれは厄介なのでしょうか?

0
Bluemoon10