C# 从非异步运行async(),无需等待
在我的代码中,QueueTasks()为什么不异步运行到main方法?有没有一种不同的方式来调用Is,这样它就可以了 我想要C# 从非异步运行async(),无需等待,c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,在我的代码中,QueueTasks()为什么不异步运行到main方法?有没有一种不同的方式来调用Is,这样它就可以了 我想要QueueTasks(thingsToProcess,cts.Token)启动异步方法,然后继续执行代码 当我从非异步运行异步时,一切都建议使用Task.Wait(),但我不想等待,我只想触发进程。我也在谷歌上搜索了使主线程异步,但发现了相互矛盾的建议,所以我不确定这里的确切问题是什么。我正在使用.NET4.5 class Program { private sta
QueueTasks(thingsToProcess,cts.Token)
启动异步方法,然后继续执行代码
当我从非异步运行异步时,一切都建议使用Task.Wait(),但我不想等待,我只想触发进程。我也在谷歌上搜索了使主线程异步,但发现了相互矛盾的建议,所以我不确定这里的确切问题是什么。我正在使用.NET4.5
class Program
{
private static SemaphoreSlim maxThreads = new SemaphoreSlim(5);
private static readonly object syncLock = new object();
private static readonly Random getrandom = new Random();
private static int inQueue = 0;
public static int GetRandomNumber(int min, int max)
{
lock (syncLock)
{ // synchronize
return getrandom.Next(min, max);
}
}
static async Task DoSomething(string input, int row, SemaphoreSlim theSem)
{
theSem.Wait();
inQueue++;
int delay = GetRandomNumber(0, 5000);
await Task.Delay(delay);
Console.WriteLine(String.Format("{0}: Doing something to {1}", row,input));
inQueue--;
theSem.Release();
}
static async Task QueueTasks(List<string> things, CancellationToken ct)
{
int taskNumber = 0;
foreach (string thing in things)
{
if (ct.IsCancellationRequested)
{
Console.WriteLine("No more tasks being queued");
break;
}
else
{
maxThreads.Wait();
DoSomething(thing, ++taskNumber, maxThreads);
maxThreads.Release();
}
}
}
static void Main(string[] args)
{
// build list of 100 random strings to represent input
List<string> thingsToProcess = new List<string>();
for (int i = 0; i < 100; i++)
{
thingsToProcess.Add(Path.GetRandomFileName());
}
Console.WriteLine("Starting queue");
CancellationTokenSource cts = new CancellationTokenSource();
// I want this to initiate a queue starting but not stop the flow of code.
QueueTasks(thingsToProcess, cts.Token);
// This should run immediately after queue starts
Console.WriteLine("Hit X to stop current queue");
ConsoleKeyInfo cancel = Console.ReadKey();
while (cancel.KeyChar != 'x')
{
cancel = Console.ReadKey();
}
if (cancel.KeyChar == 'x')
{
cts.Cancel();
Console.WriteLine(String.Format("You requested a cancellation. {0} threads left to process", inQueue));
}
else
{
Console.WriteLine("Operation completed without interuption");
}
Console.ReadLine();
}
}
类程序
{
私有静态信号量lim maxThreads=新信号量lim(5);
私有静态只读对象syncLock=新对象();
private static readonly Random getrandom=new Random();
私有静态int inQueue=0;
公共静态整数GetRandomNumber(整数最小值,整数最大值)
{
锁定(同步锁定)
{//同步
返回getrandom.Next(最小值、最大值);
}
}
静态异步任务DoSomething(字符串输入、int行、信号量lim-theSem)
{
theSem.Wait();
inQueue++;
int delay=GetRandomNumber(0,5000);
等待任务。延迟(延迟);
WriteLine(String.Format(“{0}:对{1}”、行、输入执行操作));
排队--;
释放;
}
静态异步任务队列任务(列出内容、取消令牌ct)
{
int taskNumber=0;
foreach(事物中的字符串)
{
如果(ct.IsCancellationRequested)
{
WriteLine(“不再有任务排队”);
打破
}
其他的
{
maxThreads.Wait();
DoSomething(thing、++taskNumber、maxThreads);
maxThreads.Release();
}
}
}
静态void Main(字符串[]参数)
{
//生成100个随机字符串的列表以表示输入
List thingsToProcess=new List();
对于(int i=0;i<100;i++)
{
thingsToProcess.Add(Path.GetRandomFileName());
}
Console.WriteLine(“起始队列”);
CancellationTokenSource cts=新的CancellationTokenSource();
//我希望它能够启动队列,但不会停止代码流。
QueueTasks(thingsToProcess,cts.Token);
//这应该在队列启动后立即运行
WriteLine(“点击X停止当前队列”);
ConsoleKeyInfo cancel=Console.ReadKey();
while(cancel.KeyChar!=“x”)
{
cancel=Console.ReadKey();
}
如果(cancel.KeyChar=='x')
{
cts.Cancel();
WriteLine(String.Format(“您请求了一个取消,剩下{0}个线程要处理”,inQueue));
}
其他的
{
Console.WriteLine(“操作完成,无中断”);
}
Console.ReadLine();
}
}
async
不是一个神奇地使您的方法异步的关键字!它只允许您在其中使用wait
关键字,而您没有这样做。您的方法是完全同步的,因此在完成之前不会返回
如果您确实在某个时候使用了wait
,这时QueueTasks
将返回,您可以继续执行Main
除此之外,您的代码是非常线程不安全的,所以您很幸运它实际上没有运行多线程(实际上,它确实运行在多个线程上,但至少一次只运行大约2-3个线程):)多线程的一个很好的开端是
您可以做的最简单的事情就是将QueueTasks
方法包装在Task.Run
中。这将导致它在与被调用方并行的新线程上运行
第二个最简单的方法是在“等待”信号量时在QueueTasks
中使用Wait
,Wait maxThreads.WaitAsync()
而不是maxThreads.Wait
。请注意,您应该删除DoSomething
中的等待-您正在丢弃信号量插槽;实际上很有可能像这样死锁代码(所有五个插槽都被外部Wait
占用,这将阻止DoSomething
中的Wait
解锁)
最困难的事情是实际学习如何通过并行执行和节流正确处理生产者-消费者队列。同样,它是一个很好的启动工具:)
async
不是一个神奇地使方法异步的关键字!它只允许您在其中使用wait
关键字,而您没有这样做。您的方法是完全同步的,因此在完成之前不会返回
如果您确实在某个时候使用了wait
,这时QueueTasks
将返回,您可以继续执行Main
除此之外,您的代码是非常线程不安全的,所以您很幸运它实际上没有运行多线程(实际上,它确实运行在多个线程上,但至少一次只运行大约2-3个线程):)多线程的一个很好的开端是
您可以做的最简单的事情就是将QueueTasks
方法包装在Task.Run
中。这将导致它在与被调用方并行的新线程上运行
第二个最简单的方法是在“等待”信号量时在QueueTasks
中使用Wait
,Wait maxThreads.WaitAsync()
而不是maxThreads.Wait
。请注意,您应该删除DoSomething
中的等待-您正在丢弃信号量插槽;实际上,很可能会像这样死锁代码(所有五个插槽都被外部占用Wait
,这将阻止