I've created an Azure Function that is triggered by a timer, which connects to a storage queue and grabs the next few messages, it runs every minute:
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage;
using Newtonsoft.Json;
using VS.Core.JobRunner;
namespace VS.JobRunner {
public static class JobRunner {
[FunctionName("JobRunner")]
public static void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, TraceWriter log) {
var storageAccount = CloudStorageAccount.Parse(
"DefaultEndpointsProtocol=https;AccountName=xxxxxxxxx;AccountKey=xxxxxxxxxxxxxxxxxxxxxxxx;EndpointSuffix=core.windows.net");
var queueClient = storageAccount.CreateCloudQueueClient();
var queueWait = queueClient.GetQueueReference("jobs-waiting-uat");
var queueProcessing = queueClient.GetQueueReference("jobs-processing-uat");
var messages = queueWait.GetMessages(10, TimeSpan.FromSeconds(55));
foreach (var message in messages) {
log.Info($"Processing {message.AsString}");
queueWait.DeleteMessage(message);
try {
var jobMessage = JsonConvert.DeserializeObject<JobMessage>(message.AsString);
if (jobMessage.ExecuteTime <= DateTime.Now) {
log.Info($"Send message to processing queue.");
queueProcessing.AddMessage(message);
} else {
log.Info($"Requeue message.");
queueWait.AddMessage(message);
}
} catch (Exception ex) {
log.Error(ex.Message);
}
}
}
}
}
It deploys to Azure with no issues, and happily runs and does its thing. But when I try to run it locally to do some testing, it fails with the following:
[07/03/2018 18:09:01] Reading host configuration file 'C:\github\vs\VS.Jobs\VS.JobRunner\bin\UAT\net462\host.json'
[07/03/2018 18:09:01] Host configuration file read:
[07/03/2018 18:09:01] {}
[07/03/2018 18:09:01] Generating 1 job function(s)
[07/03/2018 18:09:01] Starting Host (HostId=vslaptopbg2-470926380, Version=2.0.11415.0, ProcessId=26736, Debug=False, ConsecutiveErrors=0, StartupCount=1, FunctionsExtensionVersion=~1)
[07/03/2018 18:09:01] Found the following functions:
[07/03/2018 18:09:01] VS.JobRunner.JobRunner.Run
[07/03/2018 18:09:01]
Listening on http://localhost:7071/
Hit CTRL-C to exit...
[07/03/2018 18:09:02] Host lock lease acquired by instance ID '0000000000000000000000009A12D146'.
[07/03/2018 18:09:02] Function started (Id=00f03472-4bee-4fe9-a8af-29e0ea4a1e8b)
[07/03/2018 18:09:02] Executing 'JobRunner' (Reason='Timer fired at 2018-03-07T18:09:02.4920152+00:00', Id=00f03472-4bfe-4fe9-a8af-29e0ea4a1e8b)
[07/03/2018 18:09:02] A ScriptHost error has occurred
[07/03/2018 18:09:02] Exception while executing function: JobRunner. VS.JobRunner: Method not found: 'System.Collections.Generic.IEnumerable`1<Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage> Microsoft.WindowsAzure.Storage.Queue.CloudQueue.GetMessages(Int32, System.Nullable`1<System.TimeSpan>, Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)'.
[07/03/2018 18:09:02] Exception while executing function: JobRunner
[07/03/2018 18:09:02] Exception while executing function: JobRunner. VS.JobRunner: Method not found: 'System.Collections.Generic.IEnumerable`1<Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage> Microsoft.WindowsAzure.Storage.Queue.CloudQueue.GetMessages(Int32, System.Nullable`1<System.TimeSpan>, Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)'.
[07/03/2018 18:09:02] Function completed (Failure, Id=00f03472-4bfe-4fe9-a8af-29e0ea4a1e8b, Duration=158ms)
[07/03/2018 18:09:02]
[07/03/2018 18:09:02] Executed 'JobRunner' (Failed, Id=00f03472-4bfe-4fe9-a8af-29e0ea4a1e8b)
[07/03/2018 18:09:02] System.Private.CoreLib: Exception while executing function: JobRunner. VS.JobRunner: Method not found: 'System.Collections.Generic.IEnumerable`1<Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage> Microsoft.WindowsAzure.Storage.Queue.CloudQueue.GetMessages(Int32, System.Nullable`1<System.TimeSpan>, Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)'.
[07/03/2018 18:09:02] Function had errors. See Azure WebJobs SDK dashboard for details. Instance ID is '00f03472-4bfe-4fe9-a8af-29e0ea4a1e8b'
[07/03/2018 18:09:02] System.Private.CoreLib: Exception while executing function: JobRunner. VS.JobRunner: Method not found: 'System.Collections.Generic.IEnumerable`1<Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage> Microsoft.WindowsAzure.Storage.Queue.CloudQueue.GetMessages(Int32, System.Nullable`1<System.TimeSpan>, Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions, Microsoft.WindowsAzure.Storage.OperationContext)'.
[07/03/2018 18:09:02] The next 5 occurrences of the schedule will be:
[07/03/2018 18:09:02] 07/03/2018 18:10:00
[07/03/2018 18:09:02] 07/03/2018 18:11:00
[07/03/2018 18:09:02] 07/03/2018 18:12:00
[07/03/2018 18:09:02] 07/03/2018 18:13:00
[07/03/2018 18:09:02] 07/03/2018 18:14:00
[07/03/2018 18:09:02]
[07/03/2018 18:09:02] Job host started
^CTerminate batch job (Y/N)? y
I'm guessing its missing a reference to Microsoft.WindowsAzure.Storage somewhere, but where do I add this reference? I've tried adding WindowsAzure.Storage nuget package, but it still errors.
References
Microsoft.NET.Sdk.Functions v1.0.6
Newtonsoft.Json v11.0.1
UPDATE
I tried adding WindowsAzure.Storage v9.0.1 to the project, but that results in a different error:
[08/03/2018 09:47:55] A ScriptHost error has occurred
[08/03/2018 09:47:55] Exception while executing function: JobRunner. VS.JobRunner: Could not load file or assembly 'Microsoft.WindowsAzure.Storage, Version=9.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly 'Microsoft.WindowsAzure.Storage, Version=9.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
You are clearly struggling with version conflicts. Azure Functions are sensitive to problems when multiple versions of the same library are referenced. To avoid them:
Microsoft.NET.Sdk.Functions
to the latest version.WindowsAzure.Storage
explicitly, it should only be referenced transitively from Microsoft.NET.Sdk.Functions
.After converting my class library from .Net 2.0 to .Net 4.6.1 (long story!), I started getting the above mentioned error on runtime in my Azure function - "Could not load file or assembly 'Microsoft.WindowsAzure.Storage, Version=9.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly 'Microsoft.WindowsAzure.Storage, Version=9.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'."
Turns out the Azure function that uses this library was using a .Net SDK NuGet package of 1.08 which uses WindowsAzure.Storage version 7.2.1. But I was using WindowsAzure.Storage version 9.1.0.0 explicitly in my class library (latest stable version always isnt it !!!).
It took me a while but found that the version numbers are referenced in a config file (func.exe.config) for functions; for me this was in C:\Users\\AppData\Local\Azure.Functions.Cli\1.0.9. This had 7.2.1 in it, my function also had the same but my class library had the latest version and so it was complaining about it.
Went back to the older version of the package in my class library and my function started working properly. Hope this helps!
User contributions licensed under CC BY-SA 3.0