Определения, если текущий поток выполнения


С помощью C# создать класс, который получает действие (параметр-менее делегировать) в своей конструкции и имеет один открытый метод типа bool выполнить() , которая выполняет следующие действия:

  • Действие выполняется только если никакой другой поток выполнения действий

  • Если другой поток уже выполняется, подождите, пока поток закончится, прежде чем вернуться снова (но без выполнения действий)

  • Возвратите true, если текущий поток выполняет это действие, в противном случае возвращает false.

public delegate bool Action();

private static int ThreadsCount = 100; //initialize threads count

static void Main(string[] args)
{
    Action act = Execute;
    bool t = act();
    Console.WriteLine(t);
    Console.ReadLine();
}

static bool Execute()
{
    bool retVal = false;
    Thread thread = Thread.CurrentThread;
    string s = thread.Name;
    if (s == null)
    {
        test();
        retVal = true;
    }
    else
    {
        ThreadsCount = ThreadsCount - 1;

        if (ThreadsCount < 1)
        {
            //if all threads finished executing do whatever you wanna do here..
            Console.WriteLine("C# language");
            test();
            retVal = true;
        }
        else
        {
            retVal = false;
        }

    }
    return retVal;
}

private static void test()
{
    Console.WriteLine("C# language");
}

Это выше кусок кода, правильно? Пожалуйста, дайте мне ваши отзывы.

Пожалуйста, не думайте, что это просто упражнение. Этот вопрос был задан одним из интервьюеров.



Комментарии
1 ответ

Нужно смотреть на то, как вы можете сделать выполнить способ как нить-безопасный и верный требований метода. Вы говорите, что он должен возвращать true только в том случае, когда делегат на самом деле называется, но вы должны убедиться, что только один поток может вызвать ее одновременно. Вот где замок входит. Вы могли бы потенциально сделать что-то вроде:

public class SingleCallAction
{
private readonly object sync = new object();
private readonly Action action;
private bool executed;

public SingleCallAction(Action action)
{
if (action == null)
throw new ArgumentNullException("action");

this.action = action;
}

public bool Execute()
{
if (!executed)
{
lock(sync)
{
if (!executed)
{
action();
executed = true;
return true;
}
}
}

return false;
}
}

Теперь, что этот класс является оберткой вокруг действий делегата. Мы используем действий , поскольку он поддерживает как делегировать задания, или лямда назначения.

В Выполнить способ сначала проверить, чтобы увидеть, если она уже была выполнена (если у него есть, спрыгнуть вниз, чтобы возвратить false; а не поток, который заключил делегат.

Если не выполняется, то будет блокировка по синхронизации объектов для предотвращения любых других потоков выполнения внутри блока кода. Компилятор генерирует монитор.Введите и отслеживать.Выход здесь для вас, стоит прочитать!

После замка, мы проверяем, был ли исполнен флаг установлен снова. Это позволяет избежать условий гонки для конкурирующих потоков. Не беспокойтесь о расе условия при работе с выполнен флаг, а переменная читает/пишет всегда атомарных операций (в основном).

Если мы первый поток для выполнения делегата, мы можем выполнить это действие(), установите флаг как выполняется, и возвращает true.

Любые последующие вызовы всегда будут ложными.

Для использования в коде:

var action = new SingleCallAction(() => Console.WriteLine("Executed"));

var thread1 = new Thread(() => Console.WriteLine(action.Execute()));
var thread2 = new Thread(() => Console.WriteLine(action.Execute()));

thread1.Start();
thread2.Start();

В результате:

Executed
True
False

4
ответ дан 11 июня 2011 в 09:06 Источник Поделиться