Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在一个线程中多次执行smth直到成功?_C#_.net_Multithreading_Parallel Processing - Fatal编程技术网

C# 如何在一个线程中多次执行smth直到成功?

C# 如何在一个线程中多次执行smth直到成功?,c#,.net,multithreading,parallel-processing,C#,.net,Multithreading,Parallel Processing,我想让每个玩家都有一条线索来猜一个数字。 但现在我每次都创建一个线程,并得到一个内存不足异常。 如何修复它?如何使一个线程猜测数字,直到获胜。 我希望有尽可能多的线程作为球员和执行功能,直到有人赢了 static void Main(string[] args) { object lockObject = new object(); bool isGameOver = false; int weightOfBasket = Game.

我想让每个玩家都有一条线索来猜一个数字。 但现在我每次都创建一个线程,并得到一个内存不足异常。 如何修复它?如何使一个线程猜测数字,直到获胜。 我希望有尽可能多的线程作为球员和执行功能,直到有人赢了

  static void Main(string[] args)
    {
        object lockObject = new object();
        bool isGameOver = false;

        int weightOfBasket = Game.SetWeightForBasket();
        Console.WriteLine("Real weight : " + weightOfBasket);

        Console.WriteLine("Count of players in this game?");
        var countOfPlayers = Convert.ToInt32(Console.ReadLine());

        var players = new List<IPlayer>();
        for (int i = 0; i < countOfPlayers; i++)
        {
            IPlayer player = null;
            Console.WriteLine("Player's name:");
            string playerName = Console.ReadLine();
            Console.WriteLine("Player's type:");
            string playerType = Console.ReadLine();
            bool isExist = playerType != null && Enum.IsDefined(typeof(Game.Type), value: playerType);
            if (isExist)
            {
                Type type = Type.GetType("TestTask_game." + playerType + "Player");
                if (type != null)
                {
                    player = (IPlayer)Activator.CreateInstance(type);
                }
                if (player != null)
                {
                    player.Name = playerName;
                    player.Type = playerType;
                    players.Add(player);
                }
            }
        }
        while (!isGameOver)
        {
            Parallel.ForEach(players, new ParallelOptions(),
                (player, i, j) =>
                {
                    ThreadPool.QueueUserWorkItem(o => TryToGuess(player, weightOfBasket, out isGameOver, ref lockObject));
                });
        }
        FindClosestToWinPlayer(players, weightOfBasket);
        Console.ReadLine();
    }

 private static void TryToGuess(IPlayer player, int weightOfBasket, out bool IsWinner, ref object objectToLock)
    {
        lock (objectToLock)
        {
            if (_overallAmountOfAttempts == Game.AttemptsLimit)
            {
                IsWinner = true;
                Thread.CurrentThread.Join();
                return;
            }
            _overallAmountOfAttempts++;

            int numberToGuess = player.GetNumberToGuess();
            Game.AllNumberAttempts.Add(numberToGuess);

            Console.WriteLine("Number is " + numberToGuess + "?");
            Console.WriteLine("Attempt was made by " + player.Name);

            if (numberToGuess == weightOfBasket)
            {
                Console.WriteLine(player.Name + " is a winner. Count of attempts = " + player.CountOfAttempts);
                IsWinner = true;
                Thread.CurrentThread.Join();
            }
            else
            {
                int delta = weightOfBasket - numberToGuess;
                Thread.Sleep(Math.Abs(delta) * 1000);
                IsWinner = false;
            }
            Console.WriteLine(_overallAmountOfAttempts);
        }
    }
static void Main(字符串[]args)
{
对象锁定对象=新对象();
bool-isGameOver=false;
int-weightOfBasket=Game.setweightofBasket();
Console.WriteLine(“实际重量:+箱子重量”);
Console.WriteLine(“此游戏中的玩家数?”);
var countOfPlayers=Convert.ToInt32(Console.ReadLine());
var players=新列表();
对于(int i=0;i
{
QueueUserWorkItem(o=>TryToGuess(播放器,盒子的重量,out-isGameOver,ref-lockObject));
});
}
FindClosestToInplayer(玩家、背包重量);
Console.ReadLine();
}
私有静态void TryToGuess(IPlayer玩家,背包的整数权重,out bool IsWinner,ref object objectToLock)
{
锁定(对象锁定)
{
if(_overallAmountOfAttempts==Game.AttemptsLimit)
{
IsWinner=true;
Thread.CurrentThread.Join();
返回;
}
_总尝试次数++;
int numberToGuess=player.GetNumberToGuess();
Game.AllNumberAttempts.Add(numberToGuess);
Console.WriteLine(“数字为“+numberToGuess+”?”);
Console.WriteLine(“尝试由“+player.Name”进行);
if(numberToGuess==箱子的重量)
{
Console.WriteLine(player.Name+”是赢家。尝试次数=“+player.CountOfAttempts”);
IsWinner=true;
Thread.CurrentThread.Join();
}
其他的
{
int delta=箱子的重量-数字猜测;
线程睡眠(数学绝对值(增量)*1000);
IsWinner=false;
}
控制台写入线(_overallAmountOfAttempts);
}
}

您需要仔细考虑多线程是否是您所需要的,大多数情况下并非如此。这是一个相当复杂的问题,在最好的时候很难做到正确

在while循环中,您几乎一直在创建新线程,据我所知,在while循环中,条件永远不会变为false。此外,您在同一对象上锁定了TryToGuess函数,这使得多线程毫无意义——一次只有一个线程会进入锁

如果您真的决定必须使用多线程,这里更好的方法是只为每个播放器创建一次线程,然后让它们运行到完成,并在运行时同步它们。此外,使用任务或其他更高级别的抽象,而不是手动处理多线程

编辑:不管怎么说,这似乎都是一个高度串行化的过程-玩家轮换,只有一个控制台。。。这就是为什么我说多线程可能不是正确的方法


编辑:但是如果你真的想使用多线程,为了好玩或者学习,我想,你必须考虑到在播放器线程和主线程之间需要大量的通信。他们需要知道轮到他们的时候,他们需要回答球员是否赢了。所以我能想到的一个合理的方法是给每个玩家发信号,当轮到玩家时发信号,然后线程运行,然后主线程检查一些共享状态,看它是否应该停止(在每个玩家之后或者在一个回合之后),这意味着主线程需要等待,直到播放器线程完成一个回合。我真的看不到不违背多线程目的的替代方案,抱歉:)

我完全不知道如何在一个线程中多次运行函数,直到成功?您可以在while循环或类似的方式中运行它,与任何其他代码一样。例如
while(true){mySemaphore.WaitOne();/*do stuff*/mySemaphore.Release();if(condition)break;}
(我只是不假思索地键入了这个,所以请不要把它作为最佳实践的示例)