如何解决杀死C#中的任务
在处理生成温度曲线的异步任务时,我遇到了一些问题。
Dim X as Long
X = 2
MsgBox Cells(X,X).Address 'it will return the address of Row 2,Columns 2 ($B$2)
'Or
MsgBox Range("A" & X).Address 'returns "$A$2"
然后我用回车按钮点击功能的另一种形式调用它。
public static async Task genLotProfile(string lotno,string filename,string datch)
{
int count = 0;
while (true)
{
count += 1;
//Move this following code to new method
var csv = new StringBuilder();
if (!File.Exists(filename))
{
File.Create(filename);
}
Tprofile temp = getLogData(datch);
if (count == 1)
{
var header = string.Format("Lotno,Temperature,Date,DataChannel");
csv.AppendLine(header);
}
var newLine = string.Format("{0},{1},{2},{3}",lotno,temp.temperature,temp.date,temp.dataChannel);
csv.AppendLine(newLine);
if (!File.Exists(filename))
{
File.WriteAllText(filename,csv.ToString());
}
File.AppendAllText(filename,csv.ToString());
//task delay
await Task.Delay(30000);
}
}
在我的案例中,杀死一个任务有哪些惯例?
解决方法
请勿对await Task.Delay(30000)
使用无限循环。
请改为使用间隔为30秒的计时器。然后在必要时停止计时器。
如果涉及WPF UI元素,请使用DispatcherTimer。如果您使用的是.NET Core,还请使用File
方法的异步版本:
private readonly DispatcherTimer timer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(30)
};
public MainWindow()
{
InitializeComponent();
timer.Tick += OnTimerTick;
timer.Start();
}
private async void OnTimerTick(object sender,EventArgs e)
{
...
if (!File.Exists(filename))
{
await File.WriteAllTextAsync(filename,csv.ToString());
}
else
{
await File.AppendAllTextAsync(filename,csv.ToString());
}
...
}
随时通过
停止计时器timer.Stop();
,
Clemens所说的话似乎几乎与您的用例完全匹配,因为您实际上希望每30秒执行一次,然后在用户请求时停止。
但是,从另一个角度回答您的问题,“杀死任务”的典型方法是CancellationTokenSource + CancellationToken。令牌是充当标记的东西,它表示“立即死亡”(开始虚假,可以一次设置为真实状态,不可清除),源是标志的控制器,允许您升起标志。
请记住,尽管这是“取消任务的标准方法”,但这不是强制停止的方法。该任务必须定期检查该令牌,并查看其是否已取消。
现在您可能想知道为什么要拥有这样的令牌,为什么不仅仅使用volatile / atomic / bool / etc。答案是:CancellationToken是一次性的,它可以作为值传递,与其他对象合并/链接,在设置时订阅以获取回调,它具有CancellationToken.ThrowIfCancellation方法,该方法引发可以快速摆脱任何嵌套的if / switch / while / for的异常-框架可以理解此异常,并且希望可以处理该异常,并且不会使进程崩溃,以及(...)
最重要的是,它被人们认可。如果有人看到CancellationToken,就知道它是要中断/停止/中断某些处理。
每当您考虑使用bool
阻止某事时,请改用CancellationToken。
编辑:我要写一个例子,但是迈克尔·兰德尔击败了我:)
,唯一的惯例是我们不使用Abort
中止线程。
肯定的办法是使用合作社CancellationToken
。如果您需要长时间运行的任务来进行IO work
和/或UI更新,那么这将是理想的选择。否则,您也可以像值得Clemens的answer中那样使用Timer
public static async Task GenLotProfile(string lotno,string filename,string datchm,CancellationToken token)
{
try
{
int count = 0;
while (!token.IsCancellationRequested)
{
//...
await Task.Delay(30000,token);
}
}
catch (OperationCanceledException e)
{
// if you want to suppress the task cancelled exception that may be thrown
}
_logger.Debug("GenLotProfile Cancelled");
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。