让我们以一点点诚实开始吧.我不是goto的粉丝,但我也不是一遍又一遍地重复我的代码的粉丝.无论如何,我遇到了这种情况.这是不寻常的,但不是出于这个世界.我不禁想知道这是否适合goto.有没有更好的办法?
public Task Process(CancellationTokenSource token) { await SpinUpServiceAsync(); foreach (var item in LongList()) { if (token.IsCancellationRequested) goto cancel; await LongTask1(item); if (token.IsCancellationRequested) goto cancel; await LongTask2(item); if (token.IsCancellationRequested) goto cancel; await LongTask3(item); if (token.IsCancellationRequested) goto cancel; await LongTask4(item); if (token.IsCancellationRequested) goto cancel; await LongTask5(item); continue; cancel: { Log($"Cancelled during {item}"); await SpinDownServiceAsync(); return; } } }
这是我看到的下一个最佳选择:
public Task Process(CancellationTokenSource token) { await SpinUpServiceAsync(); foreach (var item in LongList()) { if (token.IsCancellationRequested) { Log($"Cancelled during {item}"); await SpinDownServiceAsync(); return; } await LongTask1(item); if (token.IsCancellationRequested) { Log($"Cancelled during {item}"); await SpinDownServiceAsync(); return; } await LongTask2(item); if (token.IsCancellationRequested) { Log($"Cancelled during {item}"); await SpinDownServiceAsync(); return; } await LongTask3(item); if (token.IsCancellationRequested) { Log($"Cancelled during {item}"); await SpinDownServiceAsync(); return; } await LongTask4(item); if (token.IsCancellationRequested) { Log($"Cancelled during {item}"); await SpinDownServiceAsync(); return; } await LongTask5(item); } }
但看看那不必要的重复.
谢谢你的考虑.
解决方法
我没有LongTask1-5的确切类型,但我会这样做.
public Task Process(CancellationTokenSource token) { SOMETYPE[] tasks = new SOMETYPE[] {LongTask1,LongTask2,LongTask3,LongTask4,LongTask5}; await SpinUpServiceAsync(); foreach (var item in LongList()) { foreach(var task in tasks){ if (token.IsCancellationRequested) { Log($"Cancelled during {item}"); await SpinDownServiceAsync(); return; } await task(item); } } }
这种方法将任务放在一个数组中.如果需求发生变化,需要更多任务,那么数组定义会变长,但其余代码保持不变.好的代码使用循环来执行重复性任务,而不是像原始帖子中那样的大量复制和粘贴.