C# 使用ManualResetEvent、CancellationTokenSource和后台线程,实现数据获取和界面刷新的启动、继续、暂停和停止功能 给出完整程序
时间: 2024-09-12 21:04:59 浏览: 47
在C#中,我们可以使用`ManualResetEvent`、`CancellationTokenSource`以及后台线程来实现数据获取的异步操作,并配合UI更新的控制。以下是一个简单的示例,展示了如何创建一个后台线程来定期获取数据,同时提供开始、继续、暂停和停止的功能:
```csharp
using System;
using System.Threading;
using System.Threading.Tasks;
class DataFetcher
{
private ManualResetEvent _startEvent = new ManualResetEvent(false);
private CancellationTokenSource _cancellationTokenSource;
private bool _isPaused = false;
private Thread _dataThread;
public async Task StartAsync()
{
_cancellationTokenSource = new CancellationTokenSource();
_dataThread = new Thread(DataFetchTask);
_dataThread.Start();
// 等待开始事件被设置
await _startEvent.WaitOne();
if (!_cancellationTokenSource.IsCancellationRequested)
Console.WriteLine("Data fetching started.");
}
public void Continue()
{
_isPaused = false;
_startEvent.Set();
}
public void Pause()
{
_isPaused = true;
}
public void Stop()
{
_cancellationTokenSource.Cancel();
_dataThread.Join(); // 等待线程结束
_dataThread = null;
_startEvent.Close();
}
private async void DataFetchTask()
{
while (!(_cancellationTokenSource.IsCancellationRequested || _isPaused))
{
try
{
// 模拟异步数据获取
var data = await Task.Delay(500, _cancellationTokenSource.Token);
// 在这里添加实际的数据获取和处理逻辑
// 更新UI的操作可以放在另一个线程,以避免阻塞主线程
// await UpdateUiWithNewData(data);
Console.WriteLine($"Got new data after {data} ms");
}
catch (OperationCanceledException)
{
Console.WriteLine("Data fetch was cancelled.");
break;
}
}
}
// 这里只是一个占位符,你可以将其替换为真正的UI更新方法
private async Task UpdateUiWithNewData(string newData)
{
// 在单独的UI更新线程中执行
await Task.Run(() => Application.Current.Dispatcher.Invoke(() =>
{
// UI相关更新逻辑,比如改变文本框内容等
}));
}
}
public class Program
{
public static void Main()
{
var fetcher = new DataFetcher();
fetcher.StartAsync();
// 示例操作
Console.WriteLine("Press enter to continue...");
Console.ReadLine();
fetcher.Continue();
Console.WriteLine("Press 'P' to pause, 'Q' to quit:");
char input = Console.ReadKey().KeyChar;
switch (input)
{
case 'P':
fetcher.Pause();
break;
case 'Q':
fetcher.Stop();
break;
}
}
}
```
这个例子中,`StartAsync`方法会启动数据获取任务并在主线程等待启动信号。当用户输入时,我们调用`Continue`来唤醒并继续数据获取。`Pause`方法将暂停任务,而`Stop`方法则取消任务并关闭相关资源。
注意:在实际应用中,你可能会使用`BackgroundWorker`或者`async/await`结合`Task`来简化线程管理,或者使用.NET框架提供的`CancellationToken`更方便地取消任务。此外,UI更新部分需要你自己根据你的具体UI技术栈来编写。
阅读全文