2017-02-26 3 views
0

J'ai un rôle de travailleur, donc quand je le déploie, ça marche une fois et puis ne faites rien, voici mon code, comment puis-je résoudre ce problème? J'ai seulement changé cet endroit, la fonction OnStart et OnStop est par défaut.Azure Worker Rôle de travail juste au démarrage

public class WorkerRole : RoleEntryPoint 
{ 
    private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); 
    private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false); 

    public override void Run() 
    { 
     Thread.Sleep(10000); 
     Trace.TraceInformation("WorkerRole is running"); 

     while(true) 
     { 
      try 
      { 
       this.RunAsync(this.cancellationTokenSource.Token).Wait(); 
      } 
      finally 
      { 
       this.runCompleteEvent.Set(); 
      } 
     } 
    } 

    public override bool OnStart() 
    { 
     ServicePointManager.DefaultConnectionLimit = 12; 
     bool result = base.OnStart(); 
     Trace.TraceInformation("WorkerRole has been started"); 
     return result; 
    } 

    public override void OnStop() 
    { 
     Trace.TraceInformation("WorkerRole is stopping"); 

     this.cancellationTokenSource.Cancel(); 
     this.runCompleteEvent.WaitOne(); 

     base.OnStop(); 

     Trace.TraceInformation("WorkerRole2 has stopped"); 
    } 

    public byte[] imageToByteArray(System.Drawing.Image imageIn) 
    { 
     MemoryStream ms = new MemoryStream(); 
     imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
     return ms.ToArray(); 
    } 


    private CloudBlobContainer GetImageBlobContainer() 
    { 
     var storageAccount = CloudStorageAccount.Parse("myconnectionstring"); 
     var blobClient = storageAccount.CreateCloudBlobClient(); 
     var container = blobClient.GetContainerReference("cadblob"); 
     container.CreateIfNotExists(); 

     container.SetPermissions(
      new BlobContainerPermissions 
      { 
       PublicAccess = BlobContainerPublicAccessType.Blob 
      }); 
     return container; 
    } 

    public static Image ScaleImage(Image image, int maxWidth, int maxHeight) 
    { 
     var ratioX = (double)maxWidth/image.Width; 
     var ratioY = (double)maxHeight/image.Height; 
     var ratio = Math.Min(ratioX, ratioY); 

     var newWidth = (int)(image.Width * ratio); 
     var newHeight = (int)(image.Height * ratio); 

     var newImage = new Bitmap(newWidth, newHeight); 
     Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight); 
     return newImage; 
    } 

    private async Task RunAsync(CancellationToken cancellationToken) 
    { 
     CloudStorageAccount storageAccount = CloudStorageAccount.Parse("Myconnectionstring");    
     CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();   
     CloudQueue queue = queueClient.GetQueueReference("cadqueue");    
     CloudQueueMessage retrievedMessage = queue.GetMessage(); 

     if (retrievedMessage.AsString != null || retrievedMessage.AsString != "") 
     { 
      string[] msg = retrievedMessage.AsString.Split(' '); 

      CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); 
      CloudTable table = tableClient.GetTableReference("cadtable"); 

      TableOperation retrieveOperation = TableOperation.Retrieve<ImageEntity>("Images", msg[0]); 
      TableResult retrievedResult = table.Execute(retrieveOperation); 
      var container = GetImageBlobContainer(); 
      msg[2] = "mini_" + msg[2]; 
      CloudBlockBlob blockBlob = container.GetBlockBlobReference(msg[2]); 
      blockBlob.Properties.ContentType = msg[1]; 

      Image img; 
      var webClient = new WebClient(); 
      byte[] imgBytes = webClient.DownloadData(((ImageEntity)retrievedResult.Result).Full_img); 
      using (var ms = new MemoryStream(imgBytes)) 
      { 
       img = Image.FromStream(ms); 
      } 
      Image thumb = ScaleImage(img, 220, 160); 
      var fileBytes = imageToByteArray(thumb); 
      await blockBlob.UploadFromByteArrayAsync(fileBytes, 0, fileBytes.Length); 

      ImageEntity ent = (ImageEntity)retrievedResult.Result; 
      if (ent != null) 
      { 
       ent.Mini_img = "https://cadwebstorage.blob.core.windows.net/cadblob/" + msg[2]; 
       TableOperation insertOrReplaceOperation = TableOperation.InsertOrReplace(ent); 
       table.Execute(insertOrReplaceOperation); 
      } 
      else 
      { 
       Console.WriteLine("Entity could not be retrived."); 
      } 

      queue.DeleteMessage(retrievedMessage); 
     } 


     while (!cancellationToken.IsCancellationRequested) 
     { 
      Trace.TraceInformation("Working"); 
      await Task.Delay(10000); 
     } 
    } 

} 
+0

Pouvez-vous poster toute la classe ici? –

+0

Ouais, bien sûr, je vais éditer mon post pour le rendre clair. – oceankit

Répondre

2

La raison pour laquelle votre code de mise à l'échelle de l'image ne fonctionne qu'une fois à cause de cette boucle

while (!cancellationToken.IsCancellationRequested) 
     { 
      Trace.TraceInformation("Working"); 
      await Task.Delay(10000); 
     } 

intérieur private async Task RunAsync(CancellationToken cancellationToken). Cela ne se termine jamais sauf si vous arrêtez l'instance de travail. Pour résoudre ce problème, vous pouvez mettre le code de traitement d'image dans la boucle comme celui-ci

private async Task RunAsync(CancellationToken cancellationToken) 
     { 
      while (!cancellationToken.IsCancellationRequested) 
      { 
       ScaleImage(); 
       await Task.Delay(10000); 
      } 
     } 

     private void ScaleImage() 
     { 
      Trace.TraceInformation("Scaling Image"); 
      CloudStorageAccount storageAccount = CloudStorageAccount.Parse("Myconnectionstring"); 
      CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); 
      CloudQueue queue = queueClient.GetQueueReference("cadqueue"); 
      CloudQueueMessage retrievedMessage = queue.GetMessage(); 

      if (retrievedMessage.AsString != null || retrievedMessage.AsString != "") 
      { 
       string[] msg = retrievedMessage.AsString.Split(' '); 

       CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); 
       CloudTable table = tableClient.GetTableReference("cadtable"); 

       TableOperation retrieveOperation = TableOperation.Retrieve<ImageEntity>("Images", msg[0]); 
       TableResult retrievedResult = table.Execute(retrieveOperation); 
       var container = GetImageBlobContainer(); 
       msg[2] = "mini_" + msg[2]; 
       CloudBlockBlob blockBlob = container.GetBlockBlobReference(msg[2]); 
       blockBlob.Properties.ContentType = msg[1]; 

       Image img; 
       var webClient = new WebClient(); 
       byte[] imgBytes = webClient.DownloadData(((ImageEntity)retrievedResult.Result).Full_img); 
       using (var ms = new MemoryStream(imgBytes)) 
       { 
        img = Image.FromStream(ms); 
       } 
       Image thumb = ScaleImage(img, 220, 160); 
       var fileBytes = imageToByteArray(thumb); 
       await blockBlob.UploadFromByteArrayAsync(fileBytes, 0, fileBytes.Length); 

       ImageEntity ent = (ImageEntity)retrievedResult.Result; 
       if (ent != null) 
       { 
        ent.Mini_img = "https://cadwebstorage.blob.core.windows.net/cadblob/" + msg[2]; 
        TableOperation insertOrReplaceOperation = TableOperation.InsertOrReplace(ent); 
        table.Execute(insertOrReplaceOperation); 
       } 
       else 
       { 
        Console.WriteLine("Entity could not be retrived."); 
       } 

       queue.DeleteMessage(retrievedMessage); 
      } 

     } 

et vous n'avez pas besoin de la boucle while(true) en Run(). Le Run() peut être simple comme ceci

public override void Run() 
     { 
      try 
      { 
       RunAsync(cancellationTokenSource.Token).Wait(); 
      } 
      finally 
      { 
       runCompleteEvent.Set(); 
      } 
     } 
+0

Merci beaucoup, ça marche bien! – oceankit

+0

@oceankit pouvez-vous accepter la réponse? –