それは明らかです。たとえば、私のフォームのボタンを想像してみてください。ユーザーがボタンをクリックすると、一部の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回実行する必要があり、タイマーを使用するとプログラムが読みにくくなるため、タイマーを使用することは私の最後の意見です。だから私はもしあればもっと良い解決策を探しています。それともタイマーを使用する必要があるのでしょうか?
私はスレッドで遊ぶ必要があると思いますが、確かではありません。だから、誰かが私を解決策に導くことができるかどうか疑問に思います。前もって感謝します。
タスクを使用できますか?
Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(Interval);
TheMethod();
});
これは、.Net 4.5の非同期待機機能を使用できる場所です。
Task.Delayを使用して、ミリ秒単位の遅延を与えることができます。これは非常にクリーンな方法です。例:
private async void button1_Click(object sender, EventArgs e)
{
await Task.Delay(5000);
TheMethod();
}
Coroutine
を作成する必要があります
public IEnumerator waitAndRun()
{
// WAIT FOR 3 SEC
yield return new WaitForSeconds(3);
// RUN YOUR CODE HERE ...
}
そしてそれを次のように呼び出します:
StartCoroutine(waitAndRun());
を使用して正確な秒を指定できます
DateTime runTime = new DateTime();
double waitSeconds = (runTime - DateTime.Now).TotalSeconds;
Task.Factory.StartNew(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(waitSeconds));
YourMethod();
});
runTime =>メソッドを実行する場合。
ここにあなたが欲しいものがあります:
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....
}
お役に立てば幸いです。
別のオプションは、スレッドを処理する必要があるときはいつでもスレッドを作成し、スリープオプションを気にしないことです。プロセスをロードするたびに新しいスレッドを作成するだけです
DoAfterDelayは、1回だけ実行されるタイマーを開始します。タイマーが期限切れになると、void 'TheMethod'関数が呼び出されます。なぜこれは厄介なのでしょうか?