IG.NORE PLS,我对此进行了修改,但无法删除
创建了一个项目,该项目将创建随机生成的凭据,然后对其执行命令。我的问题是,我不知道如何将所有变量锁定为1个单线程,因为我希望将其多线程化。截至目前,我的变量都是全局变量。
例如-
namespace Project
{
class ClassName
{
int test = 0;
int test22 = 0;
}
大多数变量是全局变量,而不是方法中的变量,因此任何方法都可以访问它们(需要)。最终,在线程完成其工作之后,它将保存凭据-这就是问题所在。如果有10个线程创建了一个凭据,请继续工作,因为这10个线程共享相同的变量,因此仅保存1个凭据(c的所有重复项)。
共享变量的方法示例-
static void CreateCredentials()
{
string boyname = "";
string boyname = "";
rnd.Next(0, 55);
string boyname = "jack";
}
因此,其他方法最终将使用该“帐户名”和“帐户密码”,但是我想将用于1个线程的所有变量锁定。因此,每个线程上都有不同的“帐户名”和“帐户密码”数据。
我尝试通过参数发送变量,但是看起来很混乱,看着任务,但是我有很多变量,所以再次变得非常混乱。
是否可以将所有变量锁定到线程?如果是这样,我该怎么办?
答案 0 :(得分:0)
这里是一个不需要锁定的示例,因为这些字段被封装在自己的类中。该类仅由单个线程使用,因此不需要锁。
class Program
{
private static Random _rnd = new Random();
private static Faker _facer = new Faker();
static void Main(string[] args)
{
List<Task> tasks = new List<Task>();
List<CredentialHelper> credentials = new List<CredentialHelper>();
//Start Tasks parallel
for (int i = 0; i < 10; i++)
{
//Init helper
var credentialHelper = new CredentialHelper(i.ToString());
credentials.Add(credentialHelper);
//Start task
tasks.Add(Task.Factory.StartNew(() => credentialHelper.CreateCredentials(_rnd, _facer)));
}
//Wait
Task.WaitAll(tasks.ToArray());
//Output
foreach (var credentialHelper in credentials)
{
Console.WriteLine("{0}:{1}",credentialHelper.AccountName, credentialHelper.AccountPassword);
}
}
}
internal class CredentialHelper
{
internal String AccountName { get; private set; }
internal String AccountPassword { get; private set; }
internal CredentialHelper(String accountName)
{
this.AccountName = accountName;
}
internal void CreateCredentials(Random rnd, Faker faker)
{
// Add use of faker here...
//Wait random just to show work
Thread.Sleep(rnd.Next(100, 600));
//Set password
AccountPassword = rnd.Next(0, 999).ToString();
}
}
答案 1 :(得分:0)
我不确定您的线程如何工作,但是您可以使用ConcurrentDictionary存储每个线程ID的凭据。
public class Credentials
{
public string AccountName { get; set; }
public string AccountPassword { get; set; }
}
public class CredentialBuilder
{
public static ConcurrentDictionary<int, Credentials> credentialDictionary = new ConcurrentDictionary<int, Credentials>();
public static void CreateCredentials()
{
var credentials = new Credentials();
string firstname = "";
string lastname = "";
//real name or not - 1/4 chances on using real
switch (rnd.Next(1, 13)) //1-12
{
case 1:
firstname = Faker.NameFaker.FirstName();
lastname = Faker.NameFaker.LastName();
break;
case 2:
firstname = Faker.NameFaker.FirstName();
lastname = customnames[rnd.Next(customnames.Count)];
break;
case 3:
firstname = customnames[rnd.Next(customnames.Count)];
lastname = Faker.NameFaker.LastName();
break;
default:
firstname = customnames[rnd.Next(customnames.Count)];
lastname = customnames[rnd.Next(customnames.Count)];
break;
}
credentials.AccountName = firstname + lastname;
credentials.AccountPassword = rnd.Next(0, 999);
credentialDictionary.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, credentials, (k, v) => credentials);
}
private static Credentials GetCredentials()
{
Credentials credentials;
var threadId = Thread.CurrentThread.ManagedThreadId;
return credentialDictionary.TryGetValue(threadId, out credentials)?
credentials :
null;
}
public static string AccountName
{
get
{
var credentials = GetCredentials();
return credentials != null? credentials.AccountName: string.Empty;
}
}
public static string AccountPassword
{
get
{
var credentials = GetCredentials();
return credentials != null ? credentials.AccountPassword : string.Empty;
}
}
}