我想在工作人员在后台运行时显示通知。我可以用下面的代码来做到这一点:
override suspend fun doWork(): Result {
val manager = NotificationManagerCompat.from(applicationContext)
val channel = "some_channel"
val id = 15
val builder = NotificationCompat.Builder(applicationContext, channel)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
manager.createNotificationChannel(NotificationChannel(channel, "DefaultName", NotificationManager.IMPORTANCE_LOW))
builder
.setOnlyAlertOnce(true)
.setOngoing(true)
.setAutoCancel(false)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setTicker("Background Task")
.setContentText("Starting")
.setProgress(0, 0, true)
setForeground(ForegroundInfo(id, builder.build()))
delay(500)
manager.notify(id, builder.setContentText("Progress A").setProgress(20, 0, false).build())
for (i in 1..20) {
delay(100)
manager.notify(id, builder.setProgress(20, i, false).build())
}
delay(500)
manager.notify(id, builder.setContentText("Progress B").setProgress(2, 0, false).build())
delay(1000)
manager.notify(id, builder.setProgress(2, 1, false).build())
delay(1000)
manager.notify(id, builder.setProgress(2, 2, false).build())
delay(1000)
manager.notify(id, …
Run Code Online (Sandbox Code Playgroud) 假设我有很多生产者,1个消费者未绑定 Channel,有一个消费者:
await foreach (var message in channel.Reader.ReadAllAsync(cts.Token))
{
await consume(message);
}
Run Code Online (Sandbox Code Playgroud)
问题在于该consume
函数会进行一些 IO 访问,并且可能还会进行一些网络访问,因此在消耗 1 条消息之前可能会产生更多消息。但由于IO资源不能并发访问,所以我不能有很多消费者,也不能把函数扔到consume
一个Task中然后忘记它。
该consume
功能可以轻松修改以获取多条消息并批量处理它们。所以我的问题是,是否有一种方法可以让消费者在尝试访问通道队列时获取通道队列中的所有消息,如下所示:
while (true) {
Message[] messages = await channel.Reader.TakeAll();
await consumeAll(messages);
}
Run Code Online (Sandbox Code Playgroud)
编辑:我能想到的 1 个选项是:
List<Message> messages = new();
await foreach (var message in channel.Reader.ReadAllAsync(cts.Token))
{
await consume(message);
Message msg;
while (channel.Reader.TryRead(out msg))
messages.Add(msg);
if (messages.Count > 0)
{
await consumeAll(messages);
messages.Clear();
}
}
Run Code Online (Sandbox Code Playgroud)
但我觉得这应该是一个更好的方法来做到这一点。