Сообщите, что ActionBlock завершен в другой класс - PullRequest
0 голосов
/ 01 мая 2020

Я написал метод для реализации TPL ActionBlock, который будет выполнять функцию поиска XPath элемента, который я отправляю в блок. Я отправляю элемент из приложения в реальном времени (всякий раз, когда пользователь находит элемент Опубликовать его в блок). Теперь я хочу проверить, завершен блок или нет, когда я вызываю кнопку сохранения из другого класса. Лог c - это если ActionBlok завершено, когда мы нажимаем элемент кнопки «Сохранить», то сохранится с некоторыми логами сохранения c, в противном случае отобразится окно сообщения, еще не готовое. Впервые эта идея работает, но со второго элемента Actionblock не принимает ничего. Я использую block.Complete() и block.Completion.Wait() для проверки сохранения. Теперь я могу показать, что звоню по коду / логи c.

  1. После создания элемента опубликуйте его ActionBlock
    Class1
......
jobQ.Enqueue(familarizedElement);
......
Внутри ActionBlock
Class2
public class TPLCommonDataFlow
{
    private ActionBlock<Element> _jobs;
    public static bool TPLFlowStatus = false;
    public static string JobStatus = string.Empty;
    public TPLCommonDataFlow()
    {
        var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions()
        {
            MaxDegreeOfParallelism = 2,
        };

        _jobs = new ActionBlock<Element>((job) =>
        {
            Thread.Sleep(5);
            File.WriteAllText("C:\\Temp\\A.txt", "Started" + _jobs.InputCount.ToString());
            JobStatus = "started";
            Familiarization.FindAndUpdateXPath(job);
            File.WriteAllText("C:\\Temp\\A.txt", "Finished");
        }, executionDataflowBlockOptions);
        _jobs.Complete();


        //Wait for all messages to propagate through the network
        _jobs.Completion.Wait();

        //Checking all jobs are completed or not, if completed changing the boo, value.
        if (_jobs.InputCount == 0)
        {
            TPLFlowStatus = true;
            JobStatus = "stoped";
        }
    }
}
Для сохранения я проверяю логическое значение TPLFlowStatus
Class3
if (class2.TPLFlowStatus == true)
{
    //Save Logic
}
else
{
    //Message Box showing Not Ready
}

Теперь я хочу проверять каждый раз, когда задание выполнено или нет каждый элемент в логе сохранения c. Если блок, имеющий два элемента в Queue и один из них завершен, то MessageBox должен появиться после нажатия кнопки сохранения. Если все выполнено в блоке, то нужно go сохранить логи c.

1 Ответ

0 голосов
/ 04 мая 2020

Проблема, которую вы видите, состоит в том, что, когда блок завершен, он больше не будет принимать новые сообщения, вы сказали блоку, что вы закончили отправку сообщений. Чтобы начать отправку нового пакета сообщений, вы можете либо сохранить блок в активном состоянии, не вызывая завершения и не отслеживая завершение пакета другим способом, либо просто сбросив блок. Простой работник вроде этого может быть тем, что вы ищете:

public class DataflowWorker
{
    private ActionBlock<string> _jobs;

    private void BuildJobsHandler()
    {
        _jobs = new ActionBlock<string>(x => Console.WriteLine(x) /*Do your work in the action block*/);
    }

    public async Task Enque(string element)
    {
        await _jobs.SendAsync(element);
    }

    public async Task CompleteJobsAndSave()
    {
        _jobs.Complete();
        await _jobs.Completion;
        //Save data when complete
        BuildJobsHandler();
    }
}
...