BeginInvoke Why is the first invoke finished first? - asynchronous

I was testing delegates and ive stopped on BeginInvoke and EndInvoke. I wonder what happen in this fellowing code.
I though that the first begin invoke would terminate after the second since the second is only 2 seconds and the first one is 3 seconds. Don't this make it like its a sync call ? Why ?
It seem the actual call is only called when EndInvoke is used.
/// <summary>
/// Démonstration d'un appel d'une méthode ASYNCRONE avec BeginInvoke() SANS rappel (Callback).
/// </summary>
public class AsyncBeginInvokeDemo
{
// Voici la méthode délégué.
// L'équivalent: Func<int, string> (Func<In1, ..., Out>)
// Note: Aurait pu être également Action<int> si la méthode ne retourne pas de valeurs.
delegate string MethodDelegate(int iCallTime, string message);
/// <summary>
/// Démarrer la démonstration.
/// </summary>
public void Start()
{
string strReturnedData = String.Empty;
// Attaché la méthode au délégué.
MethodDelegate dlgt = new MethodDelegate(this.LongRunningMethod);
// Initié l'appel asyncrone A.
IAsyncResult arA = dlgt.BeginInvoke(3000, "A est terminée!", null, null);
// Initié l'appel asyncrone B.
IAsyncResult arB = dlgt.BeginInvoke(2000, "B est terminée!", null, null);
// Retrieve the results of the asynchronous call.
strReturnedData = dlgt.EndInvoke(arA);
Console.WriteLine(strReturnedData);
strReturnedData = dlgt.EndInvoke(arB);
Console.WriteLine(strReturnedData);
}
/// <summary>
/// Il s'agit de l'opération à executé.
/// </summary>
/// <param name="iCallTime">Temps d'execution de l'opération. (Simulation)</param>
/// <returns>Données par l'opération. (Simulation)</returns>
public string LongRunningMethod(int iCallTime, string message)
{
// Mettre le thread en attente pendant un nombre de milliseconde x.
Thread.Sleep(iCallTime);
// Retourner des données.
return message;
}
}
This output :
A est terminée!
B est terminée!
Shouldn't it be ?
B est terminée!
A est terminée!

You're explicitly calling EndInvoke:
strReturnedData = dlgt.EndInvoke(arA);
That will wait until the delegate has finished. Given that you're passing in arA, it can only wait for the first delegate call to finish. It can't possibly do anything with the second delegate call, because you're explicitly saying that you want the results of the first delegate.
It seem the actual call is only called when EndInvoke is used.
No, it's just that that's when you block until the delegate has completed.
If you add this code just before return message;:
Console.WriteLine("Finished {0}", message);
Then you'll see output of:
Finished B est terminée!
Finished A est terminée!
A est terminée!
B est terminée!

Related

Generate a CSV file for Excel with Symfony

after hours of research I can't find the solution, I want to display the content of $results in an excel file I tried to do that in the download function but I can't add the table data result in the variable $myvariableCSV. i hope it's clear
<?php
namespace App\Controller\MissingPDV;
use App\Entity\Upload;
use App\Form\UploadType;
use App\Repository\UploadRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
/**
* #Route("/upload")
*/
class UploadController extends AbstractController
{
/**
* #Route("/new", name="app_upload_new", methods={"GET", "POST"})
*/
public function new(Request $request): Response
{
$upload = new Upload();
$form = $this->createForm(UploadType::class, $upload);
$form->handleRequest($request);
$results=[];
$cells1=[];
$cells2=[];
if ($form->isSubmitted() && $form->isValid()) {
//add date information
$upload->setDate(new \DateTime('now'));
$NamesOfFiles=[];
// adding File1
$file1= $form->get('file1')->getData();
$NamesOfFiles[]=$file1->getClientOriginalName();
$fileName1 =md5(uniqid()).'.csv';
$file1->move($this->getParameter('upload_directory'),$fileName1);
$upload->setFile1($fileName1);
// adding File 2
$file2= $form->get('file2')->getData();
$NamesOfFiles[]=$file2->getClientOriginalName();
$fileName2 =md5(uniqid()).'.csv';
$file2->move($this->getParameter('upload_directory'),$fileName2);
$upload->setFile2($fileName2);
// Adding text 1 fields
$text1= $form->get('text1')->getData();
$upload->setText1($text1);
// Adding text 2 fields
$text2= $form->get('text2')->getData();
$upload->setText2($text2);
// Read first File and find column according to text (Spout)
$filePath= dirname(__DIR__).'/../../public/uploads/'.$fileName1;
$reader = ReaderEntityFactory::createCSVReader();
$reader->open($filePath);
foreach ($reader->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
// do stuff with the row
$cells1[] = $row->getCells();
}
}
$reader->close();
//Reading File2 wth spout Library Reader
$filePath2= dirname(__DIR__).'/../../public/uploads/'.$fileName2;
$reader2 = ReaderEntityFactory::createCSVReader();
$reader2->open($filePath2);
foreach ($reader2->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
$cells2[] = $row->getCells();
}
}
$reader2->close();
// put in array File 1 element
$goodcolonne='';
foreach ($cells1[0] as $colonne=>$nom){
if ($nom == $text1){
$goodcolonne = $colonne;
break;
}
}
$basepdv=[];
for ($i=1;$i<count($cells1);$i++){
$basepdv[]=$cells1[$i][$goodcolonne];
}
// put in array File 2 element
foreach ($cells2[0] as $colonne=>$nom){
if ($nom == $text2){
$goodcolonne = $colonne;
break;
}
}
$newpdv=[];
for ($i=1;$i<count($cells2);$i++){
$newpdv[]=$cells2[$i][$goodcolonne];
}
// comparer et sortir les pdv manquants
foreach ($newpdv as $pdv){
if(!in_array($pdv,$basepdv)){
$results[]=$pdv;
}
}
return $this->render('vuejs/resultat.html.twig',[
'resultats' => $results,
'namesOfFiles' => $NamesOfFiles,
]);
}
// ici on charge le formulaire vide
return $this->renderForm('upload/new.html.twig', [
'upload' => $upload,
'form' => $form,
]);
}
/**
* #Route("/download", name="download")
*/
public function download($results)
{
//Nom des colonnes en première lignes
// le \n à la fin permets de faire un saut de ligne, super important en CSV
// le point virgule sépare les données en colonnes
$myVariableCSV = "code_pdv;\n";
//Ajout de données (avec le . devant pour ajouter les données à la variable existante)
$myVariableCSV .= ;\n;
//On donne la variable en string à la response, nous définissons le code HTTP à 200
return new Response(
$myVariableCSV,
200,
[
//Définit le contenu de la requête en tant que fichier Excel
'Content-Type' => 'application/vnd.ms-excel',
//On indique que le fichier sera en attachment donc ouverture de boite de téléchargement ainsi que le nom du fichier
"Content-disposition" => "attachment; filename= PDV_manquants.csv"
]
);
}
}
i try to do download fonction it's works when i add some string variables but i want do add results
If you use EasyAdmin you can export your data easily by "goodby-csv" composer. Please take a look at this link:
https://symfonycasts.com/screencast/easyadminbundle/global-action

Symfony 5 - Object of class App\Entity\Vegetal could not be converted to string

I have a problem when trying to add an image to a folder on a website that I'm developping currently. When I try to rename the file, I would like it to be : idOfMyObject.jpg
But when I want to add it on my form, this error code pops up : "Object of class App\Entity\Vegetal could not be converted to string".
The problem's apparently inside the isset, but I can't find a solution to convert my id to string.
Here is the Controller :
public function ajouterVegetal(Request $request): Response
{
$fFeuille = new FormeFeuille();
$vegetal = new Vegetal();
$formVegetal = $this->createForm(VegetalType::class, $vegetal);
$formVegetal->handleRequest($request);
//Si le formulaire est bien valide (tous les champs remplis) et que le bouton submit est appuyé
if ($formVegetal->isSubmitted() && $formVegetal->isValid()) {
//on récupère les données du formaulaire
$vegetal = $formVegetal->getData();
$entityManager = $this->getDoctrine()->getManager();
//on récupère les données de la variable image dans le formulaire d'ajout
$fileDownload = $formVegetal['images']->getData();
//si le fichier existe, on le renomme avec l'id du végétal, pour le sauvegarder dans le dossier configuré dans service.yaml
if (isset($fileDownload))
{
$nomImage = $fFeuille->getVegetals()->{$this->$vegetal->getId()}.'.'.$fileDownload->guessExtension();
$fileDownload->move(
$this->getParameter('upload_directory'),
$nomImage
);
}
//on ajoute les données dans la base
$entityManager->persist($vegetal);
$entityManager->flush();
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('listerVegetal');
} else {
return $this->render('Vegetal/ajouterVegetal.html.twig', [
'vegetal' => $vegetal,
'form' => $formVegetal->createView(),
]);
}
}
I will allow myself to assume that this error is caused when rendering the form.
And most likely you are using EntityType for Vegetal in formBilder. I'm guessing that when you render the form, you get this error because formBilder tries to convert Vegetal to render it in "select", but it fails because it doesn't know what value to take.
The code below will just help php decide what value to return when converting this object to a string.
Add in Entity Vegetal
public function __toString(): string
{
return $this->getName(); // or some string field in your Vegetal Entity
}
It also might not work for you, but usually my similar errors were solved by this.

Show the reponse with Entry

I have an Entry which is used to ask a riddle. I put certain conditions there. My guess is displayed correctly and I can enter answers but the success message does not appear.
The objective was to limit to 3 response attempts and to display a Dysplayalert in the event of an error. Otherwise, there was a Label which displayed the rest of the scenario.
What would be my mistake?
My XAML :
<!--Row 08-->
<Entry x:Name="Enigme01"
IsVisible="false"
Placeholder="Ecrire la réponse."
ClearButtonVisibility="WhileEditing"
IsTextPredictionEnabled="False"
ReturnType="Send"
Grid.ColumnSpan="2"
Grid.Row="8"/>
My XAML.CS
public void Entry_Completed (object sender, EventArgs e)
{
var reponseEnigme01 = Enigme01.Text;
string soluce1 = "chaussette";
int CompteurEnigme = 0;
while ((soluce1 != reponseEnigme01) & (CompteurEnigme < 3))
{
DisplayAlert("Info:", "Mauvaise réponse", "ok");
CompteurEnigme++;
if (CompteurEnigme >= 3)
{
Reponse04.TextColor = Color.DarkRed;
Reponse04.Text = "A force de cogiter pour trouver la réponse, vous ne voyez pas les gardes arriver. Ils vous attrapent et finisser ainsi votre carrière d'aventurier dans une geôle.";
}
}
if (reponseEnigme01 == soluce1)
{
Reponse04.Text = "Bravo, vous avez donné la bonne réponse et la porte s'ouvre.";
Reponse04.IsVisible = true;
}
}

Doctrine remove have to be done twice to work

I have a strange behavior on doctrine remove and i don't understand why.
it'an ajax delete action inside a symfony 5 controller.
If i launch the requete once = nothing appends
If i lauch the requete twice, the delete opperation occur correctly.
Why ?
thanks for your help
/**
* #Route("/permissions_ajaxDelete", name="permissions_ajaxDelete")
*/
public function ajaxDelete(Request $request)
{
$responseArray = array();
$statusCode = 200;
//if ($request->isXmlHttpRequest()) {
$id = $request->get('id');
$permission = $this->getDoctrine()->getRepository(Permissions::class)->find($id);
//test si la permission existe
if ($permission != null) {
$responseArray["successMessage"] = "La permission \"".$permission->getName()."\" d'id ".$permission->getId()." a été supprimée!";
$this->getDoctrine()->getManager()->remove($permission);
$this->getDoctrine()->getManager()->flush();
$permission = $this->getDoctrine()->getRepository(Permissions::class)->find($id);
if ($permission != null) {
dd($permission);
$responseArray["successMessage"] = "bugg";
// On a first call, permission is find after the flush/ remove
}
}else{
$responseArray["errorMessage"] = "Vous essayez de supprimer une permissions qui n'existe pas.";
$statusCode = 403;
}
return new JsonResponse($responseArray,$statusCode);
/*}else{
//Requete non ajax.
$responseArray["errorMessage"] = "Erreur : Mauvais format de requette (Ajax)";
return new JsonResponse($responseArray,400);
}*/
}
I think after the first 'find' doctrine add entity into unit of work
The second 'find' dont call data base, but only use unit of work to get entity allready loaded !
Using profiler to verify what SQL doctrine call.

Flex editable datagrid with itemEditor "combobox" not auto scroll when I edit a cell

I have a flex datagrid with dynamic columns (matrix 60 x 60 by sample) and each cell is a "combobox". My problem is when the vertical scroll position moves through any row following. How can I control this error? How can I use "verticalScrollPosition"????
<mx:DataGrid height="100%" id="dgLineRanges" editable="{editable}" itemEditBegin="modifyEditedData(event);" itemEditEnd="saveEditedData(event);" horizontalScrollPolicy="auto" visible="false"/>
I use this code:
// Handle the itemEditBegin event.
private function modifyEditedData(event:DataGridEvent):void
{
// Handle the event here.
event.preventDefault();
// El triangulo inferior no es editable
if(event.columnIndex > 0 && event.columnIndex > event.rowIndex)
{
//Buscar el rango que corresponde y actualizar su valor
selectedCell = dgLineRanges.dataProvider.getItemAt(event.rowIndex).getItemAt(event.columnIndex);
// Creates an item editor.
dgLineRanges.createItemEditor(event.columnIndex,event.rowIndex);
// All item editors must implement the IDropInListItemRenderer interface
// and the listData property.
// Initialize the listData property of the editor.
IDropInListItemRenderer(dgLineRanges.itemEditorInstance).listData =
IDropInListItemRenderer(dgLineRanges.editedItemRenderer).listData;
// Copy the cell value to the TextInput control.
dgLineRanges.itemEditorInstance.data = dgLineRanges.editedItemRenderer.data;
// Copy the cell value to the RangeComboItemEditor control.
var rangeCombo:RangeComboItemEditor = dgLineRanges.itemEditorInstance as RangeComboItemEditor;
// Sólo permitimos editar si está prohibido (pero puede permitirlo)
rangeCombo.editable = !selectedCell.forbidden;
// Esta variable se tiene en cuenta a la hora de habilitar o no los botomes de prohibido
enableForbidden(true);
// Establecer el foco
model.setRangeComboIEFocus(rangeCombo, !selectedCell.forbidden);
}
else
{
enableForbidden(false);
}
}
private function saveEditedData(event:DataGridEvent):void
{
// Check the reason for the event.
if (event.reason == DataGridEventReason.CANCELLED || event.columnIndex == 0)
{
// Do not update cell.
return;
}
// Guardamos indices de cela para facilitar posible tratamiento de botones
// prohibido / permitodo
lastRowIndex = event.rowIndex;
lastColumnIndex = event.columnIndex;
//Buscar el rango que corresponde
var stopsRange:FareOriginDestDTO = dgLineRanges.dataProvider.getItemAt(event.rowIndex).getItemAt(event.columnIndex);
if(stopsRange.saveAction == IfsConst.SAVE_ACTION_NONE)
stopsRange.saveAction = IfsConst.SAVE_ACTION_UPDATE;
// Get the new data value from the editor.
var newRangeCode:int= event.currentTarget.itemEditorInstance.code;
//Actualizar su valor
stopsRange.rangeCode = newRangeCode;
//Actualizar "Forbidden"
if (newRangeCode == -1)
stopsRange.forbidden = true;
else
stopsRange.forbidden = false;
// Simétrico (si no está en la diagonal)
if( event.rowIndex != event.columnIndex-1 )
{
stopsRange = dgLineRanges.dataProvider.getItemAt(event.columnIndex-1).getItemAt(event.rowIndex+1);
// Solo se cambia la celda simétrica si:
// Celda principal es "Forbidden" y la simétrica también
// Celda principal no es "Forbidden"
if ((newRangeCode == -1 && stopsRange.rangeCode == -1) || newRangeCode != -1)
{
if (stopsRange.saveAction == IfsConst.SAVE_ACTION_NONE)
stopsRange.saveAction = IfsConst.SAVE_ACTION_UPDATE;
stopsRange.rangeCode = newRangeCode;
}
}
// Close the cell editor.
dgLineRanges.destroyItemEditor();
// Notify the list control to update its display.
dgLineRanges.dataProvider.itemUpdated(event.itemRenderer.data);
// Mandatory dataProvider refresh
dgLineRanges.dataProvider.refresh();
// Disable copying data back to the control.
//event.preventDefault();
}

Resources