我有一群“工人”,在某些时候需要来自我的 HTTP 服务器的唯一密钥才能继续执行。这些密钥有时会在工作人员需要它们之前到达,在这种情况下,我只想为工作人员提供密钥,以便它可以继续执行。但是,如果没有剩下的键,我希望任务中的代码执行停止,直到提供键。我还希望首先使用首先提供的密钥。
我试图实现一个单例,其中可以从 HTTP 服务器提供密钥并由工作人员从中检索,但现在执行似乎陷入僵局。
我的代码:
密钥处理程序.cs
public sealed class KeyHandler
{
private static readonly KeyHandler instance = new KeyHandler();
private static Dictionary<Website, Queue<string>> retrievedKeys = new Dictionary<Website, Queue<string>>();
private static Dictionary<Website, Queue<TaskCompletionSource<string>>> waitingWorkers = new Dictionary<Website, Queue<TaskCompletionSource<string>>>();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static KeyHandler()
{
}
private KeyHandler()
{
foreach (Website website in Enum.GetValues(typeof(Website)))
{
retrievedKeys.Add(website, new Queue<string>());
waitingWorkers.Add(website, new Queue<TaskCompletionSource<string>>());
}
}
public static KeyHandler Instance
{
get
{
return instance;
}
}
public static void AddKey(Website website, string response)
{
if (waitingWorkers[website].Count > 0)
{
waitingWorkers[website].Dequeue().SetResult(response);
}
else
{
retrievedKeys[website].Enqueue(response);
}
}
public static string RetrieveKey(Website website)
{
if (retrievedKeys[website].Count > 0)
{
return retrievedKeys[website].Dequeue();
}
else
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
Task<string> t = tcs.Task;
waitingWorkers[website].Enqueue(tcs);
return t.Result;
}
}
}
工人.cs
public async Task Run()
{
...
string key = KeyHandler.RetrieveKey(Website.MyWebsite);
// do something with key here
...
}
HTTPServer.cs
private void Process(HttpListenerContext context)
{
...
KeyHandler.AddKey(Website.MyWebsite, key);
...
}