I have a C# queue trigger function that has to run async because it awaits async methods to both read and add data to tables in storage. I need to be able to exit this function early in the event of certain conditions arising, but can't figure out how to either (a) return correctly, or (b) terminate just the one instance of the function.
I originally had it coded as follows. My function works perfectly and does what it is supposed to do:
public static async void Run([QueueTrigger("myqueue"), StorageAccount("mystorge")] String transdata,
The problem is that the runtime doesn't usually like the idea of async void
, so Azure gives me an error:
System.InvalidOperationException : Functions must return Task or void, have a binding attribute for the return value, or be triggered by a binding that natively supports return values.
It clearly says right there that you can return void but obviously it doesn't actually let you, thus the error. It says the function must return Task
, so I re-coded as follows:
public static async Task Run([QueueTrigger("myqueue"), StorageAccount("mystorage")] string transdata,
That didn't work, so next I tried this:
public static async Task<Task> Run([QueueTrigger("myqueue"), StorageAccount("mystorage")] string transdata,
And tried returning early like this:
return Task.CompletedTask;
But that throws a completely different error:
Microsoft.Azure.WebJobs.Host: Cannot bind parameter '$return' to type Task&. Make sure the parameter Type is supported by the binding.
I don't NEED to return any value. I just need to end processing. So I tried finding some way to simply end the function instead of returning, and found this post which says that although you can do Environment.Exit
it will end other processes as well, so that's a no-go.
And a few extra tidbits of information in case it's relevant:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="4.0.2" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.9" />
<PackageReference Include="Twilio" Version="5.56.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
This example from Microsoft (non-Async) demonstrates using Task<string>
, so I decided to try Task<bool>
with return false;
, but that generated a similar error:
Microsoft.Azure.WebJobs.Host: Cannot bind parameter '$return' to type Boolean&.
And doing return Task.FromResult(false);
doesn't work - the IDE says that because it's Async it has to return bool
instead of Task<bool>
.
How do you simply end processing of your queue trigger function, or return correctly?
UPDATE 1: 2021-Jan-09
Although I'd already tried what has been suggested, I thought that perhaps I'd made a mistake so I should try it again. So I declared the queue trigger like this:
public static async Task Run([QueueTrigger("myqueue"), StorageAccount("mystorage")] String transdata,
And simply return normally if needed based on conditions that may arise during processing:
return;
But get the message I reported already:
Microsoft.Azure.WebJobs.Host: Error indexing method 'AddToLicenseQueue'. Microsoft.Azure.WebJobs.Host: Functions must return Task or void, have a binding attribute for the return value, or be triggered by a binding that natively supports return values.
If you leave out static
, the IDE red-underscores run
and says,
'Run': cannot declare instance members in a static class.
static
is standard in the stock/shell queue trigger function if you create a new one in Visual Studio or VS Code, or even look at Microsoft's website.