C#点击异步多重排队延迟,然后全部出列
我有一个系统,其中一个方法是用一个对象调用的,而数据库是用一个不同的对象编写的,其中有一个第一个对象的列表 目前:C#点击异步多重排队延迟,然后全部出列,c#,.net-4.5,C#,.net 4.5,我有一个系统,其中一个方法是用一个对象调用的,而数据库是用一个不同的对象编写的,其中有一个第一个对象的列表 目前: private async Task SaveAMessage(Messsage message) { var messages = new List<Message>(); messages.Add(message); var envelope = new Envelope(); envelope.messages = messages
private async Task SaveAMessage(Messsage message)
{
var messages = new List<Message>();
messages.Add(message);
var envelope = new Envelope();
envelope.messages = messages;
await _db.Save(envelope);
}
如何编写与伪代码工作方式相同的C代码?试试这段C代码(作为控制台运行):
命名空间控制台应用程序1
{
公共课程
{
专用静态异步任务SaveAMessage(字符串消息)
{
var messages=新列表();
消息。添加(消息);
返回等待保存(消息);
}
私有静态任务保存(列表消息)
{
Task Task=Task.Factory.StartNew(()=>
{
Console.WriteLine(“消息”+msg[0]+“已接收…”);
Console.WriteLine(“消息”+msg[0]+“正在运行…”);
睡眠(3000);
return“Message”+msg[0]+“finally return.”;
});
返回任务;
}
公共静态void Main(字符串[]args)
{
Task first=SaveAMessage(“Msg1”);
首先,继续使用(x=>Console.WriteLine(“Print”+x.Result));
第二个任务=保存消息(“Msg2”);
第二,继续使用(x=>Console.WriteLine(“Print”+x.Result));
任务三=保存消息(“Msg3”);
第三,继续使用(x=>Console.WriteLine(“Print”+x.Result));
任务四=保存消息(“Msg4”);
第四,继续使用(x=>Console.WriteLine(“Print”+x.Result));
任务五=保存消息(“Msg5”);
第五,继续使用(x=>Console.WriteLine(“Print”+x.Result));
Console.ReadKey();
}
}
}
您只需做一个非常简单的小改动就可以做到这一点。将whalll
添加到SaveAMessage
以等待Save
以及对任务的调用。延迟
:
private async Task SaveAMessage(Messsage message)
{
var messages = new List<Message>();
messages.Add(message);
var envelope = new Envelope();
envelope.messages = messages;
await Task.WhenAll(_db.Save(envelope), Task.Delay(1000));
}
private async Task SaveAMessage(消息)
{
var messages=新列表();
消息。添加(消息);
var信封=新信封();
envelope.messages=消息;
等待Task.WhenAll(_db.Save(信封),Task.Delay(1000));
}
现在,您可以循环执行对SaveAMessage
的所有调用,等待它们全部完成,并且您可以确保它会等待上一次保存完成,并且在继续之前至少已经过了一秒钟
如果在其他地方使用
SaveAMessage
时有时不需要等待一整秒钟,那么只需将此更改拉出,让用于保存所有消息的任何代码等待任务.Dealy
调用。新系统.Threading.Timer(())=>{Console.WriteLine(“OK”)},null,1000)代码>编辑以显示问题。计时器只会将代码延迟1秒,并始终每秒运行一次。我只想在有东西的时候跑步。我想我可以使用保护条件只保存if消息。Any()将它们全部保存1秒
您的意思是“每秒保存所有消息”(这是您的JS代码所做的),还是“立即保存所有消息,并且至少一秒钟内不允许再次保存”,或者“等待一秒钟,然后写入所有消息”,或者“至少等待一秒钟,每次收到另一条消息时重置计时器“?我的JS等待1秒钟,然后保存所有内容,然后在出现新消息之前不执行任何操作。然后等待整秒钟。这是理想的,但我也只会率限制为1卡;ll a second这绝不会添加所请求的功能,即调用SaveAMessage
的下一次调用不会比调用SaveAMessage
的前一次调用快1秒,无论Save
需要多长时间才能完成。最重要的是,在main方法中,您甚至没有将每个调用都作为另一个调用的派生,因此您可以同时执行它们。这正是他试图避免做的。@MarkKGreenway确实如此,但如果在上一条消息的任务保存完成之前不调用SaveAMessage
,则保存不会重叠,并且至少会有一秒钟的间隔,这是您要求的。我看不到任何迹象表明,应该有任何少于您的旧代码保存。
namespace ConsoleApplication1
{
public class Program
{
private static async Task<string> SaveAMessage(string message)
{
var messages = new List<string>();
messages.Add(message);
return await save(messages);
}
private static Task<string> save(List<string> msg)
{
Task<string> task = Task.Factory.StartNew<string>(() =>
{
Console.WriteLine("Message " + msg[0] + " received...");
Console.WriteLine("Message " + msg[0] + " running...");
Thread.Sleep(3000);
return "Message " + msg[0] + " finally return.";
});
return task;
}
public static void Main(string[] args)
{
Task<string> first = SaveAMessage("Msg1");
first.ContinueWith(x => Console.WriteLine("Print " + x.Result));
Task<string> second = SaveAMessage("Msg2");
second.ContinueWith(x => Console.WriteLine("Print " + x.Result));
Task<string> third = SaveAMessage("Msg3");
third.ContinueWith(x => Console.WriteLine("Print " + x.Result));
Task<string> fourth = SaveAMessage("Msg4");
fourth.ContinueWith(x => Console.WriteLine("Print " + x.Result));
Task<string> fifth = SaveAMessage("Msg5");
fifth.ContinueWith(x => Console.WriteLine("Print " + x.Result));
Console.ReadKey();
}
}
}
private async Task SaveAMessage(Messsage message)
{
var messages = new List<Message>();
messages.Add(message);
var envelope = new Envelope();
envelope.messages = messages;
await Task.WhenAll(_db.Save(envelope), Task.Delay(1000));
}