我正在处理一些后台进程。在我的控制台应用程序中有两个方法。一个private static async Task<Dictionary<string, string>> GenerateSomething()
和另一个方法发送一些东西到web服务器。与private static async SendSomething()
方法相比,generatessomething -Method要花费更多的时间。现在我有了在后台多次运行generatessomething()方法的想法,并使用返回值填充每个任务的队列。
我已经开始编程了,但我不知道如何在后台运行多个generatessomething()方法,而SendSomething()正在处理它自己。
这是我的最新结果:
class Program
{
private static Queue<Dictionary<string, string>> QueueOfDicts = new Queue<Dictionary<string, string>>();
private static int batchCount = 5000;
private static int queueMinThreshold = 10;
private static long genCounter = 0;
private static long dictCounter = 0;
private static Stopwatch stopwatch = new Stopwatch();
static void Main(string[] args)
{
GetSomething().Wait();
}
private static async Task<Dictionary<string, string>> GenerateSomething()
{
var Dict = new Dictionary<string, string>();
// Here I do some calculations which takes approximately 30 seconds
for (int i = 0; i < batchCount; i++)
{
// some calculations
}
dictCounter++;
Console.WriteLine($"Added Dict #{dictCounter} with {batchCount} to the Queue.");
return Dict;
}
private static async Task SendSomething()
{
long time = 0;
long avgTime = 0;
var counter = 0;
while (true)
{
try
{
var url = "https://.............";
var web = new Web(url);
var address = "xxxxxxxxxxx";
var service = new Service(web, address);
if (QueueOfDicts.Count > queueMinThreshold)
{
var result = QueueOfDicts.Dequeue();
Console.WriteLine("QueueCount: " + QueueOfDicts.Count);
try
{
stopwatch.Start();
// here i wait send the webresponse, which takes about 5 seconds
stopwatch.Stop();
time = stopwatch.ElapsedMilliseconds;
stopwatch.Reset();
}
catch (Exception ex)
{
await SendFailedMessage(ex);
GetSomething().Wait();
}
var index = 0;
foreach (var res in result)
{
//do something
index++;
}
genCounter += batchCount;
avgTime += time;
counter++;
if (counter >= 100000 / batchCount)
{
Console.WriteLine("Average " + avgTime / counter);
counter = 0;
avgTime = 0;
}
Console.WriteLine("{0} analyzes made -- LastCall: {1}ms", genCounter, time);
}
else
QueueOfDicts.Enqueue(await GenerateSomething());
}
catch (Exception ex)
{
Console.WriteLine("-----------ERROR----------: n End with error: n" + ex.ToString());
await SendFailedMessage(ex);
Console.WriteLine("Querytime:" + time);
Console.ReadLine();
}
}
}
private static async Task<Message> SendFailedMessage(Exception ex)
{
var Bot = new TelegramBotClient(".....");
return await Bot.SendTextMessageAsync("...", "Something went wrong: n" + ex);
}
}
谁能帮助我,我如何运行private static async Task<Dictionary<string, string>> GenerateSomething()
在后台多次,而private static async SendSomething()
做自己的工作在此期间?
希望你有足够的信息来帮助我。感谢所有帮助我完成这个小项目的人。
为了简单起见,我删除了大部分与您的内部类有关的代码。
当前在后台并行处理多个任务最简单的方法是使用async-await模式,即使用Tasks
。下面是这样的一个最小的例子,没有涉及额外的细节,如锁,线程安全等。
我建议你对c#的任务并行库感兴趣,它会对你有很大的帮助。
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
class Program
{
private static int batchCount = 5000;
private static int queueMinThreshold = 10;
static async Task Main(string[] args)
{
// Run 10 times
var arr = new Task<Dictionary<string, string>>[queueMinThreshold];
for (int i = 0; i < queueMinThreshold; i++)
{
int id = i;
arr[i] = Task.Run(async () => await GenerateSomething(id));
}
// Do whatever in the meantime
// Execute some other function call, like SendSomething()
// ...
// Finally await result of long-running operations (When all of them are finished)
await Task.WhenAll(arr);
// And, if needed, access those reults
var firstResult = arr[0].Result; // non-blocking call - it is already finished.
}
private static async Task<Dictionary<string, string>> GenerateSomething(int id)
{
var Dict = new Dictionary<string, string>();
// Here I do some calculations which takes approximately 30 seconds
for (int i = 0; i < batchCount; i++)
{
// some calculations
}
Console.WriteLine($"Added Dict #{id} with {batchCount} to the Queue.");
return Dict;
}
}