c# - C# 如何在命令行应用程序中使用异步方法运行线程
问题描述
我只是不知道如何使以下代码工作,假设在无限循环中永远运行,实际上当我await Task.Delay
从方法中删除时它会工作Method_FOO
,但我需要Method_FOO
异步。
我认为要使这项工作,该Thread.Start()
方法需要是“可等待的”(不仅仅是它运行的代码),但 Thread.Start 是无效的。我注意到,如果我用 eg.: 阻止执行,Console.ReadLine
它将打印Worked
字符串,但这不是解决方案,在现实生活中很糟糕。
这段代码只是一个例子,但是线程需要在无限循环中运行(这不是我可以改变的),并且我需要异步方法,因为我需要消耗一些 websocket,并且看起来没有同步客户端 websocket 类在 C# 中。
但是,对于这个问题,必须有一个简单/体面的解决方案。
public static class Program
{
public static async Task Main(string[] args)
{
var cancellationTokenSource = new CancellationTokenSource();
var thread1 = new Thread(async () => await Run(cancellationTokenSource.Token, "threadName1", Method_FOO));
var thread2 = new Thread(async () => await Run(cancellationTokenSource.Token, "threadName2", Method_FOO));
thread1.Start();
thread2.Start();
}
private static async Task Method_FOO(CancellationToken cancellationToken)
{
Console.WriteLine("It is called...");
await Task.Delay(300, cancellationToken);
//never reach this part
Console.WriteLine("Worked ...");
}
// workd but it is not async
//private static Task Method_FOO(CancellationToken cancellationToken)
//{
// Console.WriteLine("It is called...");
// Console.WriteLine("Worked ...");
// return Task.CompletedTask;
//}
private static async Task Run(CancellationToken cancellationToken, string threadName, Func<CancellationToken, Task> function)
{
try
{
while (true)
{
await function(cancellationToken);
Console.WriteLine($"{threadName} waiting ...");
cancellationToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(1));
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
解决方案
在历史的这一点上,new Thread
它几乎只对 COM 互操作有用。在所有其他情况下,都有更好的解决方案。在这种情况下,您可以使用以下命令将工作发送到线程池Task.Run
:
public static async Task Main(string[] args)
{
var cancellationTokenSource = new CancellationTokenSource();
var task1 = Task.Run(async () => await Run(cancellationTokenSource.Token, "threadName1", Method_FOO));
var task2 = Task.Run(async () => await Run(cancellationTokenSource.Token, "threadName2", Method_FOO));
await Task.WhenAll(task1, task2);
}
推荐阅读
- python - 使用 python flask 在同一页面中显示结果
- javascript - 调用服务器集线器方法失败
- javascript - 我正在尝试使用一些带有 codeceptjs 的本机 puppeteer 来使用其 ID 查找元素的所有方面
- c - 如何将 32 位打包成 4x8 位?
- c++ - 从源代码构建 UE4 - Mathcalls 语法错误
- sql - plpgsql 函数会产生巨大的性能开销
- php - 如何在 magento 2 phpunit 测试中进行依赖注入
- php - 未定义索引:PHP 7.2.1 中的 file_upload
- sql-server - 如何在非常大的表中获取最大日期的列名
- swift - 我希望我已经登录的用户拥有我的 ViewController3 作为 rootViewController,而那些没有登录的用户拥有 ViewController2