c# - 保持控制台打开而不中断其他功能
问题描述
即使所有等待项都已完成,如何保持控制台应用程序打开,但不会中断其他可能的等待项?
我知道我的问题听起来很奇怪,但只是为了解释一下:
我正在使用 Telegram.Bot 库,我需要收听来自电报的所有传入更新。问题是,一旦我设置了更新处理程序,控制台就会关闭。
我的另一件事是使用 RestSharp 的请求,该请求每 x 分钟从 API 获取一个 json,这可以完成使控制台保持活动状态的工作,因为我正在使用一种方法来在中断循环之前检测控制台取消。
还有另一种更好的方法来做我想做的事吗?
这就是我用于控制台近距离监听的内容https://stackoverflow.com/a/22996661/12420972
我将 exitSystem 作为 while 循环的变量
while (!exitSystem)
// Do this
解决方案
使用 while 循环将不必要地浪费 CPU 周期,因为您要做的就是等待退出信号。您可以使用TaskCompletionSource
. 下面的代码让您了解如何实现它。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp
{
public class Program
{
private static readonly TaskCompletionSource<object> TaskCompletionSrc = new TaskCompletionSource<object>();
static async Task<int> Main(string[] args)
{
Console.WriteLine("Launching background tasks...");
var thread = new Thread(DoSomethingInBackground);
thread.Start();
//wait for the task completion event
await TaskCompletionSrc.Task;
Console.WriteLine("Task completed. Exiting...");
return 0;
}
private static void DoSomethingInBackground()
{
Thread.Sleep(5000);
//signal that task has completed
TaskCompletionSrc.SetResult(null);
}
}
}
更新答案:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp
{
public class Program
{
//API call interval in milliseconds
private const int ApiCallIntervalMilliSeconds = 5000;
public static void Main(string[] args)
{
//create token source for cancelling the background operations when the main thread exists
using (var cancellationTokenSrc = new CancellationTokenSource())
//create timer which triggers the MakeApiCallback immediately and repeats for every specified milliseconds
using (var timer = new Timer(TriggerApiCall, cancellationTokenSrc, TimeSpan.Zero,
TimeSpan.FromMilliseconds(ApiCallIntervalMilliSeconds)))
{
Console.WriteLine("Program is running. Press any to exit...");
//blocks the main thread from running to completion
Console.Read();
//key press, cancel any API calls in progress
cancellationTokenSrc.Cancel();
}
}
public static async void TriggerApiCall(object argument)
{
var tokenSrc = (CancellationTokenSource) argument;
await MakeApiCall(tokenSrc.Token);
}
private static async Task MakeApiCall(CancellationToken cancellationToken)
{
Console.WriteLine("API Call in progress...");
try
{
//simulate the background work
await Task.Delay(3000, cancellationToken);
}
catch (TaskCanceledException)
{
Console.WriteLine("API call cancelled!");
return;
}
catch(Exception ex)
{
Console.WriteLine("API call failed. Exception:" + ex);
return;
}
Console.WriteLine("API call completed successfully.");
}
}
}
推荐阅读
- android - 将来自 url 的图像存储在缓存中,并将它们用作缩略图或占位符,如 whatsapp。
- eclipse - Eclipse 颜色助手背景
- json - 从键值对中“过滤”出 JSON 对象的最有效方法是什么?
- printing - 如何更改打印机 Cups 驱动程序的加网(半色调图案)?
- android - TabLayout 视觉bug:两边有灰色透明条
- java - 构造函数 ClassCountry(String, String, String, int) 未定义
- python - Curve_fit 在指数 Weibull 分布上失败
- javascript - 客户端 sdk 的 Firestore 时间戳
- unix - 从左侧提取文件字符串,但遵循右侧的第二个分隔符
- ios - Xcode 10、Swift 4.2 中的“歧义使用”