Many internal async improvements

This commit is contained in:
JustArchi
2015-10-31 05:27:30 +01:00
parent 2545e7bbf3
commit 71227168cf
5 changed files with 75 additions and 30 deletions

View File

@@ -75,12 +75,14 @@ namespace ArchiSteamFarm {
return result;
}
internal static void ShutdownAllBots() {
internal static async Task ShutdownAllBots() {
List<Task> tasks = new List<Task>();
lock (Bots) {
foreach (Bot bot in Bots) {
bot.Shutdown();
tasks.Add(Task.Run(async () => await bot.Shutdown().ConfigureAwait(false)));
}
}
await Task.WhenAll(tasks).ConfigureAwait(false);
}
internal Bot(string botName) {
@@ -203,26 +205,27 @@ namespace ArchiSteamFarm {
Task.Run(() => HandleCallbacks());
}
internal void Stop() {
internal async Task Stop() {
if (!IsRunning) {
return;
}
await CardsFarmer.StopFarming().ConfigureAwait(false);
SteamClient.Disconnect();
IsRunning = false;
}
internal void Shutdown() {
Stop();
internal async Task Shutdown() {
await Stop().ConfigureAwait(false);
lock (Bots) {
Bots.Remove(this);
}
Program.OnBotShutdown(this);
}
internal void OnFarmingFinished() {
internal async Task OnFarmingFinished() {
if (ShutdownOnFarmingFinished) {
Shutdown();
await Shutdown().ConfigureAwait(false);
}
}
@@ -312,7 +315,7 @@ namespace ArchiSteamFarm {
}
}
private void OnFriendMsg(SteamFriends.FriendMsgCallback callback) {
private async void OnFriendMsg(SteamFriends.FriendMsgCallback callback) {
if (callback == null) {
return;
}
@@ -334,6 +337,15 @@ namespace ArchiSteamFarm {
if (message.Length == 17 && message[5] == '-' && message[11] == '-') {
ArchiHandler.RedeemKey(message);
}
switch (message) {
case "!farm":
await CardsFarmer.StartFarming().ConfigureAwait(false);
break;
case "!exit":
await Shutdown().ConfigureAwait(false);
break;
}
}
private void OnPersonaState(SteamFriends.PersonaStateCallback callback) {
@@ -405,13 +417,13 @@ namespace ArchiSteamFarm {
case EResult.Timeout:
case EResult.TryAnotherCM:
Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + callback.Result + " / " + callback.ExtendedResult + ", retrying...");
Stop();
await Stop().ConfigureAwait(false);
Thread.Sleep(5000);
Start();
break;
default:
Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + callback.Result + " / " + callback.ExtendedResult);
Shutdown();
await Shutdown().ConfigureAwait(false);
break;
}
}

View File

@@ -31,20 +31,32 @@ namespace ArchiSteamFarm {
internal class CardsFarmer {
private const byte StatusCheckSleep = 5; // In minutes, how long to wait before checking the appID again
private readonly ManualResetEvent FarmResetEvent = new ManualResetEvent(false);
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
private readonly Bot Bot;
private bool NowFarming;
private readonly AutoResetEvent AutoResetEvent = new AutoResetEvent(false);
private volatile bool NowFarming = false;
internal CardsFarmer(Bot bot) {
Bot = bot;
}
internal async Task StartFarming() {
await StopFarming().ConfigureAwait(false);
await Semaphore.WaitAsync().ConfigureAwait(false);
if (NowFarming) {
Semaphore.Release();
return;
}
Logging.LogGenericInfo(Bot.BotName, "Checking badges...");
// Find the number of badge pages
HtmlDocument badgesDocument = await Bot.ArchiWebHandler.GetBadgePage(1).ConfigureAwait(false);
if (badgesDocument == null) {
Logging.LogGenericWarning(Bot.BotName, "Could not get badges information, farming is stopped!");
Semaphore.Release();
return;
}
@@ -104,7 +116,26 @@ namespace ArchiSteamFarm {
}
Logging.LogGenericInfo(Bot.BotName, "Farming finished!");
Bot.OnFarmingFinished();
await Bot.OnFarmingFinished().ConfigureAwait(false);
}
internal async Task StopFarming() {
await Semaphore.WaitAsync().ConfigureAwait(false);
if (!NowFarming) {
Semaphore.Release();
return;
}
Logging.LogGenericInfo(Bot.BotName, "Sending signal to stop farming");
FarmResetEvent.Set();
while (NowFarming) {
Logging.LogGenericInfo(Bot.BotName, "Waiting for reaction...");
Thread.Sleep(1000);
}
FarmResetEvent.Reset();
Logging.LogGenericInfo(Bot.BotName, "Farming stopped!");
Semaphore.Release();
}
private async Task<bool?> ShouldFarm(ulong appID) {
@@ -120,12 +151,6 @@ namespace ArchiSteamFarm {
}
private async Task<bool> Farm(ulong appID) {
if (NowFarming) {
AutoResetEvent.Set();
Thread.Sleep(1000);
AutoResetEvent.Reset();
}
bool success = true;
bool? keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
while (keepFarming == null || keepFarming.Value) {
@@ -133,17 +158,20 @@ namespace ArchiSteamFarm {
NowFarming = true;
Logging.LogGenericInfo(Bot.BotName, "Now farming: " + appID);
Bot.PlayGame(appID);
Semaphore.Release(); // We're farming, allow other tasks to shut us down
} else {
Logging.LogGenericInfo(Bot.BotName, "Still farming: " + appID);
}
if (AutoResetEvent.WaitOne(1000 * 60 * StatusCheckSleep)) {
if (FarmResetEvent.WaitOne(1000 * 60 * StatusCheckSleep)) {
success = false;
break;
}
keepFarming = await ShouldFarm(appID).ConfigureAwait(false);
}
Logging.LogGenericInfo(Bot.BotName, "Stopped farming: " + appID);
Bot.PlayGame(0);
NowFarming = false;
Logging.LogGenericInfo(Bot.BotName, "Stopped farming: " + appID);
return success;
}
}

View File

@@ -66,11 +66,16 @@ namespace ArchiSteamFarm {
Logging.LogGenericNotice("", "Remote version: " + remoteVersion);
Logging.LogGenericNotice("", "Consider updating yourself!");
Thread.Sleep(5000);
} else if (localVersion.CompareTo(remoteVersion) > 0) {
Logging.LogGenericNotice("", "You're currently using pre-release version!");
Logging.LogGenericNotice("", "Local version: " + localVersion);
Logging.LogGenericNotice("", "Remote version: " + remoteVersion);
Logging.LogGenericNotice("", "Be careful!");
}
}
internal static void Exit(int exitCode = 0) {
Bot.ShutdownAllBots();
internal static async Task Exit(int exitCode = 0) {
await Bot.ShutdownAllBots().ConfigureAwait(false);
Environment.Exit(exitCode);
}
@@ -121,8 +126,8 @@ namespace ArchiSteamFarm {
if (!Directory.Exists(ConfigDirectoryPath)) {
Logging.LogGenericError("Main", "Config directory doesn't exist!");
Console.ReadLine();
Exit(1);
}
Task.Run(async () => await Exit(1).ConfigureAwait(false)).Wait();
}
foreach (var configFile in Directory.EnumerateFiles(ConfigDirectoryPath, "*.xml")) {
string botName = Path.GetFileNameWithoutExtension(configFile);

View File

@@ -28,9 +28,9 @@ using System.Threading.Tasks;
namespace ArchiSteamFarm {
internal sealed class Trading {
private Bot Bot;
private readonly Bot Bot;
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
private volatile byte ParsingTasks = 0;
private SemaphoreSlim semaphore = new SemaphoreSlim(1);
internal Trading(Bot bot) {
Bot = bot;
@@ -44,7 +44,7 @@ namespace ArchiSteamFarm {
}
private async Task ParseActiveTrades() {
await semaphore.WaitAsync().ConfigureAwait(false);
await Semaphore.WaitAsync().ConfigureAwait(false);
List<SteamTradeOffer> tradeOffers = Bot.ArchiWebHandler.GetTradeOffers();
if (tradeOffers != null) {
@@ -62,7 +62,7 @@ namespace ArchiSteamFarm {
}
ParsingTasks--;
semaphore.Release();
Semaphore.Release();
}
private async Task ParseTrade(SteamTradeOffer tradeOffer) {

View File

@@ -39,7 +39,7 @@
<!-- When no bots are active, ASF will shutdown as well -->
<!-- Some people may want to keep their bots 24/7, other disconnect them after job is done -->
<!-- Choose yourself what you prefer -->
<ShutdownOnFarmingFinished type="bool" value="true"/>
<ShutdownOnFarmingFinished type="bool" value="false"/>
<!-- Comma-separated list of IDs that should not be considered for farming -->
<!-- TIP: Most likely you don't want to change it -->