在buttonWriter里用filestream 和streamwriter实现了写入,那怎么在buttonStop中用停止写入呢?
第一次编东西,不懂
你不要在buttonWriter调用死循环
把循环改为在timer里执行
然后buttonWriter启动timer
buttonStop停止timer
直接从2022年的新版开始学,2016年前的风格代码,后面可以慢慢接触(实际越往后,前面的一些古老代码实际上用的人越少,比如曾经的DataSet,DataTable,Array.Sort基本已经很难在新人代码里看到了)
新体系下直接使用 ChanelTokenSource, await/async Task 就可以完成
private CancellationTokenSource cts;
//这里有个异步信号量,使用他是因为我们会控制并行数量
//后面我会讲多任务并行需要注意控制数量和节奏,这里我控制数量1
//对相同文件操作属于数量并发控制,我不希望有多个任务同时执行
private SemaphoreSlim slim = new SemaphoreSlim(1);
private async void button2_Click(object sender, EventArgs e)
{
if (slim.CurrentCount == 0)
{
MessageBox.Show("任务已经在执行中,如需要停止,请点停止按钮");
}
await slim.WaitAsync();
cts = new CancellationTokenSource();
await WriteToFile(cts.Token);
slim.Release();
}
Task WriteToFile(CancellationToken token)
{
FileInfo fileInfo = new FileInfo("test.data");
//我这里每次都重新建立文件,如果你要是追加代码,自己根据情况修改
return Task.Run(async () =>
{
using (var fs = fileInfo.Create())
{
//对新人来说,使用write是建议方法,直接对stream操作不是不行,只是新人入门应该从标准代码开始
//如果一开始就飙车,容易学的满身坏毛病
using (StreamWriter writer = new StreamWriter(fs))
{
while (!token.IsCancellationRequested)
{
//这句话我先放在这里,但是我注销
// token.ThrowIfCancellationRequested();
writer.WriteLine($"{DateTime.Now}");
//写文件其实是先写入内存,然后由文件系统驱动刷新到文件
//这个时间不定会出现文件写了一半断掉,比如掉电,强制关闭程序等
//所以我们会手动强制要求刷新入文件
//当然还有另外的弄法,很多程序,包括vs自己,你会发现他保存的时候会先出现个临时文件,然后在删除的过程,这就是在写文件的时候防止意外情况写入不完整,这种处理顶多是信息没写上,但是文件不会有结构性损坏
writer.Flush();
}
//做多任务的时候最好,留给cpu,io一定呼吸时间,可以允许他换换气,不然他会把自己憋死
//做多任务的时候并不是任务越多越密集越好,需要控制节奏的
//注意:我轮询时间100ms,文件会长的很快,请注意不要长时间运行,不然硬盘会被我写满的
//所以如果是日志的操作,日志文件会有一些文件丢弃回滚操作,避免大量日志信息堆满整个硬盘
await Task.Delay(100);
}
}
}, token);
}
private void button3_Click(object sender, EventArgs e)
{ //上面已经都写好了,停止你就只需发一个cancel取消
cts?.Cancel();
}