csharp Неправильнаяреализацияблокировок(черезхелперы)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp Неправильнаяреализацияблокировок(черезхелперы)相关的知识,希望对你有一定的参考价值。

//Данный сниппет предназначен для демонстрации многопоточной работы с БД (добавьте текущий проект в ZennoPoster и запустите в несколько потоков)

string strDBConnString = project.Variables["cfg_db_connstring"].Value;
int intMaxTasks = Convert.ToInt32(project.Variables["cfg_tasks_per_execution"].Value);

//добавляем несколько "заданий" в таблицу db_jobs (при штатной работе фермы эта информация появлялась бы в таблице в результате других процессов)
string strAddTasksQuery = "INSERT INTO db_tasks (profile_id, task_type, post_text, post_image, object) VALUES (1, 'post', 'this is a texxt', 'image1.jpg', 'http://vk.com/supergruppa');" +
    "INSERT INTO db_tasks (profile_id, task_type, object) VALUES (2, 'like', 'https://vk.com/wall-2158488_268002');" +
	"INSERT INTO db_tasks (profile_id, task_type, object) VALUES (3, 'invite', 'https://vk.com/id139687748');" +
	"INSERT INTO db_tasks (profile_id, task_type, object) VALUES (4, 'like', 'https://vk.com/wall-2158488_636329');" +
	"INSERT INTO db_tasks (profile_id, task_type, post_text, post_image, object) VALUES (5, 'post', 'text namba tu', 'image2.jpg', 'http://vk.com/goodgruppa');";
ZennoPoster.Db.ExecuteNonQuery(strAddTasksQuery, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString);

//получаем свободный профиль (со статусом ready), для которого количество "заданий" больше нуля
//блокируем таблицу db_profiles для записи другими потоками
ZennoPoster.Db.ExecuteNonQuery("LOCK TABLES db_profiles WRITE, db_tasks READ;", null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString);
string strProfileQuery = "SELECT db_profiles.id, login, password, db_profiles.status " +
	"FROM db_profiles LEFT JOIN db_tasks ON db_profiles.id = db_tasks.profile_id " +
	"WHERE db_tasks.status='wait' " +
	"GROUP BY login, password, db_profiles.status " +
	"HAVING db_profiles.status='ready' AND COUNT(task_type)>0 " +
	"ORDER BY COUNT(db_tasks.task_type) DESC LIMIT 1;";
string strProfileQueryResult = ZennoPoster.Db.ExecuteQuery(strProfileQuery, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString, "|", Environment.NewLine);
if (String.IsNullOrEmpty(strProfileQueryResult)) {
	project.SendInfoToLog("Нет незаблокированных профилей с заданиями. Завершаем работу", true);
	goto finish;
}
string[] arrProfileParams = strProfileQueryResult.Split('|'); //обратите внимание: в данных таблицы db_profiles не должно быть символа |
string strCurrProfileID = arrProfileParams[0];
string strLogin = arrProfileParams[1];
string strPassword = arrProfileParams[2];
string strCurrProfileStatus = arrProfileParams[3];
project.SendInfoToLog(String.Format("Получили профиль с id: {0} ({1})", strCurrProfileID, strLogin), true);

//сохраняем id текущего профиля в переменной уровня проекта на случай возникновения ошибки (в этом случае по BadEnd ралочим профиль)
project.Variables["str_current_profile"].Value = strCurrProfileID;

//помечаем профиль как "занятый" (busy)
ZennoPoster.Db.ExecuteNonQuery(String.Format("UPDATE db_profiles SET status='busy', last_used=NOW() WHERE id={0};", strCurrProfileID), null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString);
//снимаем блокировку таблицы db_profiles
ZennoPoster.Db.ExecuteNonQuery("UNLOCK TABLES;", null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString);

//цикл "выполнения заданий"
int intCompletedTasks = 0; //количество выполненных заданий
do {
	//получаем задание для выполнения
	string strTasksQuery = String.Format("SELECT id, task_type, post_text, post_image, object FROM db_tasks WHERE profile_id={0} AND status='wait' LIMIT 1;", strCurrProfileID);
	string strTask = ZennoPoster.Db.ExecuteQuery(strTasksQuery, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString, "|", Environment.NewLine);
	if (strTask.Length==0) {
		project.SendInfoToLog(String.Format("Для профиля {0} ({1}) успешно выполнено {2} заданий. Больше в БД заданий нет, завершаем работу.", strCurrProfileID, strLogin, intCompletedTasks), true);
		break;
	}
	string[] arrTask = strTask.Split('|'); //обратите внимание, в данных таблицы db_tasks не должно быть символов |
	
	//получаем параметры текущего задания
	string strTaskId = arrTask[0];
	string strWhatToDo = arrTask[1];
	string strText = arrTask[2];
	string strImage = arrTask[3];
	string strTaskObject = arrTask[4];
	
	project.SendInfoToLog(String.Format("Выполняем задание id {0} ({1}) для профиля с id {2} ({3})", strTaskId, strWhatToDo, strCurrProfileID, strLogin), true);
	
	//запускаем выполнение задания
	string strTaskResultMessage = String.Empty;
	switch(strWhatToDo) {
		case "post":
			strTaskResultMessage = project.Context["fnPost"](strTaskObject, strText, strImage);
			break;
		case "like":
			strTaskResultMessage = project.Context["fnLike"](strTaskObject);
			break;
		case "invite":
			strTaskResultMessage = project.Context["fnInvite"](strTaskObject);
			break;
	}
	
	//анализируем результат выполнение задания
	string strTaskResult = String.Empty;
	if (strTaskResultMessage.StartsWith("ok:")){
		strTaskResult = "success";
	}else{
		strTaskResult = "error";
	}
	//помечаем задачу выполненной, сохраняем результат выполнения
	ZennoPoster.Db.ExecuteNonQuery(String.Format("UPDATE db_tasks SET status='{0}', status_message='{1}', change_dt=NOW() WHERE id={2};", strTaskResult, strTaskResultMessage, strTaskId), null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString);
	
	if (strTaskResultMessage.Contains("заблокирован")) {
		project.SendErrorToLog(String.Format("Профиль с id {0} ({1}) заблокирован. Завершаем работу", strCurrProfileID, strLogin));
		//отменяем все задания в базе для данного профиля (в реальности можно переназначать задания на "любой" профиль)
		ZennoPoster.Db.ExecuteNonQuery(String.Format("UPDATE db_tasks SET status='cancelled', status_message='profile blocked', change_dt=NOW() WHERE profile_id={0} AND status='wait';", strCurrProfileID), null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString);
		strCurrProfileStatus = "blocked"; //меняем статус профиля в переменной на blocked
		break; //прерываем цикл выполнения заданий
	}
	
	intCompletedTasks++;
	
} while (intCompletedTasks<intMaxTasks);

//помечаем профиль как "свободный" (ready). блокировка таблицы при этом не требуется
ZennoPoster.Db.ExecuteNonQuery(String.Format("UPDATE db_profiles SET status='{0}', last_used=NOW() WHERE id={1};", strCurrProfileStatus, strCurrProfileID), null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, strDBConnString);

finish:
return "oki";

//ПРИМЕЧАНИЯ:
//1.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;

namespace ZennoLab.OwnCode
{
    /// <summary>
	/// A simple class of the common code
	/// </summary>
	public class CommonCode
	{
		/// <summary>
		/// Lock this object to mark part of code for single thread execution
		/// </summary>
		public static object SyncObject = new object();

		// Insert your code here
	}
}

以上是关于csharp Неправильнаяреализацияблокировок(черезхелперы)的主要内容,如果未能解决你的问题,请参考以下文章

比特币不能购买特斯拉了!今日比特币狂跌背后的原因……

sql Задание1.ДолжновыполнятьсясиспользованиемMySQL(иприжеланиисPHP)Преобразоватьданныетаблицытакимоб

php WP is_page - правильноеиспользованиеопределениястраницвfunction.php

html Пропорциональноеизмененияразмеровблока

La Sylphide 仙女

scss Правильноразделяемзапятымиэлементысписков