使用多个变量的多线程多方法

时间:2018-11-21 06:13:01

标签: c# multithreading

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个线程的所有变量锁定。因此,每个线程上都有不同的“帐户名”和“帐户密码”数据。

我尝试通过参数发送变量,但是看起来很混乱,看着任务,但是我有很多变量,所以再次变得非常混乱。

是否可以将所有变量锁定到线程?如果是这样,我该怎么办?

2 个答案:

答案 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;
        }
    }

}