我想在我的任務完成五次后開始一個任務。這可能以簡單的方式嗎?我不能用一個簡單的計時器來做到這一點,因為我的客戶自己在任務中設定時間。當我設定一個計時器時,應該在第五輪之后開始的任務在錯誤的時間開始。
我有一個程式,其任務(8 個任務)一個接一個地開始和結束。然后最后一個任務再次開始第一個任務。我不知何故需要一個計數器,在第五輪結束時計數。所以最后一個任務必須第五次完成,然后我想要包含的這個特定任務應該自動打開,如果它們完成了,然后自己啟動第一個任務。
這是我的異步任務..它從按鈕開始并重復..它只是一個最小化的版本。
async void STARTCLICK(CancellationToken token)
{
for (int i = 0; i < 2; i )
{
try
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
if ()
{
}
}
catch (AggregateException)
{
MessageBox.Show("Expected");
}
catch (ObjectDisposedException)
{
MessageBox.Show("Bug");
}
catch { }
}
Thread.Sleep(2000);
var t2 = Task.Run(() => START(token));
await Task.WhenAny(new[] { t2 });
}
async void START(CancellationToken token)
{
for (int i = 0; i < 10; i )
{
try
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
if ()
{
}
}
catch (AggregateException)
{
Console.WriteLine("Expected");
}
catch (ObjectDisposedException)
{
Console.WriteLine("Bug");
}
catch { }
}
Thread.Sleep(7000);
var t3 = Task.Run(() => MOVE(token));
await Task.WhenAny(new[] { t3 });
}
async void MOVE(CancellationToken token)
{
for (int i = 0; i < 4; i )
{
try
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
if ()
{
}
}
catch (AggregateException)
{
Console.WriteLine("Expected");
}
catch (ObjectDisposedException)
{
Console.WriteLine("Bug");
}
catch { }
}
var t4 = Task.Run(() => RESTART(token));
await Task.WhenAny(new[] { t4 });
}
async void RESTART(CancellationToken token)
{
for (int i = 0; i < 4; i )
{
try
{
token.ThrowIfCancellationRequested();
await Task.Delay(100, token);
if ()
{
}
}
catch (AggregateException)
{
Console.WriteLine("Expected");
}
catch (ObjectDisposedException)
{
Console.WriteLine("Bug");
}
catch { }
}
var t4 = Task.Run(() => STARTCLICK(token));
await Task.WhenAny(new[] { t4 });
is it possible to script it like this? REPAIR is the Task that i need only each 5th time... i need the token canccelation in my tasks. because the Tasks are very big and schould be stopped anytime.
Repair is a Task between EXITACCEPT and RESTART.

uj5u.com熱心網友回復:
您實作無限遞回回圈的方式有點粗略。維護它應該是相當困難的。我的建議是洗掉異步方法之間的依賴關系/互動,并將以回圈方式呼叫它們的責任委托給“主”異步方法,該方法在while回圈中順序呼叫它們:
async Task InfiniteLoopAsync()
{
long iteration = 0;
while (true)
{
iteration ;
await Method_A();
await Method_B();
await Method_C();
await Method_D();
if (iteration % 5 == 0) await Method_E();
}
}
每個方法都應該有一個Task回傳型別,而不是void:
async Task Method_A()
{
}
最后你可以像這樣開始無限回圈:
private async void Button1_Click(object sender, EventArgs args)
{
await InfiniteLoopAsync();
}
Click事件處理程式應該是您唯一帶有async void簽名的方法。
uj5u.com熱心網友回復:
使用SemaphoreSlim最大計數為 5 的 a。這意味著一次最多可以有 5 個執行緒進入此信號量。一旦所有五個執行緒都用完,執行特殊任務并釋放信號量上的 5 個執行緒。沖洗并重復。
這是一個例子。警告:TaskRepeater類是錯誤的(例如例外處理)。
using System;
using System.Threading;
using System.Threading.Tasks;
var taskRepeater = new TaskRepeater(async () => await RepeatedTaskAsync(), 5);
await taskRepeater.RunAsync(async () => await RegularTaskAsync("A"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("B"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("C"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("D"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("E"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("F"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("G"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("H"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("I"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("J"));
await taskRepeater.RunAsync(async () => await RegularTaskAsync("K"));
static async Task RepeatedTaskAsync()
{
Console.WriteLine("Running repeated task.");
await Task.Delay(500);
}
static async Task RegularTaskAsync(string id)
{
Console.WriteLine($"Running regular task {id}.");
await Task.Delay(50);
}
public class TaskRepeater
{
private readonly int frequency;
private readonly Func<Task> repeatTaskFactory;
private readonly SemaphoreSlim semaphore;
private readonly SemaphoreSlim repeatSemaphore;
public TaskRepeater(Func<Task> repeatTaskFactory, int frequency)
{
this.frequency = frequency;
this.repeatTaskFactory = repeatTaskFactory;
this.semaphore = new SemaphoreSlim(frequency, frequency);
this.repeatSemaphore = new SemaphoreSlim(1, 1);
}
public async Task RunAsync(Func<Task> taskFactory)
{
try
{
await this.semaphore.WaitAsync();
await taskFactory.Invoke();
if (this.semaphore.CurrentCount == 0 && this.repeatSemaphore.CurrentCount != 0)
{
await this.PerformRepeatedTaskAsync();
}
}
catch (Exception)
{
if (this.semaphore.CurrentCount == 0)
{
this.semaphore.Release();
}
if (this.repeatSemaphore.CurrentCount > 0)
{
this.repeatSemaphore.Release();
}
throw;
}
}
private async Task PerformRepeatedTaskAsync()
{
await this.repeatSemaphore.WaitAsync();
if (this.semaphore.CurrentCount > 0)
{
this.repeatSemaphore.Release();
return;
}
await this.repeatTaskFactory.Invoke();
this.semaphore.Release(frequency);
this.repeatSemaphore.Release();
}
}
這輸出:
Running regular task A.
Running regular task B.
Running regular task C.
Running regular task D.
Running regular task E.
Running repeated task.
Running regular task F.
Running regular task G.
Running regular task H.
Running regular task I.
Running regular task J.
Running repeated task.
Running regular task K.
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/451701.html
標籤:c# visual-studio if-statement task
