[英]Azure Web Jobs / Queue - DecoderFallbackException
I am using the Azure Web Jobs Feature.我正在使用 Azure Web 作业功能。 Here is what I do.这就是我所做的。
Step 1第1步
SimpleClass
which has just one property with always the same string from the same client application.我有一个名为SimpleClass
的简单类,它只有一个属性,并且始终具有来自同一客户端应用程序的相同字符串。 (The string is APA91bELkr6CyBmqLbWomwkI2zw_GkXGVsblYH60l4hERXw9ZkCcXufjJM_7IZXI5_Ry9aze6AhYRVzBfl6CYq0kxrdV4ViPkW5hK2Rd2HlsZCDfhnOc3PGLt_SzIMjfbMRug_eK_di2YbJTA6weczoTyb-dKuvnwg
) (该字符串是APA91bELkr6CyBmqLbWomwkI2zw_GkXGVsblYH60l4hERXw9ZkCcXufjJM_7IZXI5_Ry9aze6AhYRVzBfl6CYq0kxrdV4ViPkW5hK2Rd2HlsZCDfhnOc3PGLt_SzIMjfbMRug_eK_di2YbJTA6weczoTyb-dKuvnwg
Step 2第2步
But I got an exception sometime (only sometimes, this sucks)但有时我会遇到一个例外(只是有时,这很糟糕)
Unhandled Exception: System.Text.DecoderFallbackException: Unable to translate bytes [FF] at index 4 from specified code page to Unicode.
at System.Text.DecoderExceptionFallbackBuffer.Throw(Byte[] bytesUnknown, Int32 index)
at System.Text.DecoderExceptionFallbackBuffer.Fallback(Byte[] bytesUnknown, Int32 index)
at System.Text.DecoderFallbackBuffer.InternalFallback(Byte[] bytes, Byte* pBytes)
at System.Text.UTF8Encoding.GetCharCount(Byte* bytes, Int32 count, DecoderNLS baseDecoder)
at System.String.CreateStringFromEncoding(Byte* bytes, Int32 byteLength, Encoding encoding)
at System.Text.UTF8Encoding.GetString(Byte[] bytes, Int32 index, Int32 count)
at Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage.get_AsString()
at Microsoft.Azure.Jobs.QueueCausalityHelper.GetOwner(CloudQueueMessage msg)
at Microsoft.Azure.Jobs.Host.Runners.Worker.GetFunctionInvocation(FunctionDefinition func, RuntimeBindingProviderContext context, CloudQueueMessage msg)
at Microsoft.Azure.Jobs.Host.Runners.Worker.MyInvoker.Microsoft.Azure.Jobs.ITriggerInvoke.OnNewQueueItem(CloudQueueMessage msg, QueueTrigger trigger, RuntimeBindingProviderContext context)
at Microsoft.Azure.Jobs.Host.Triggers.PollQueueCommand.TryExecute()
at Microsoft.Azure.Jobs.LinearSpeedupTimerCommand.Execute()
at Microsoft.Azure.Jobs.IntervalSeparationTimer.RunTimer(Object state)
at System.Threading.TimerQueueTimer.CallCallbackInContext(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.TimerQueueTimer.CallCallback()
at System.Threading.TimerQueueTimer.Fire()
at System.Threading.TimerQueue.FireQueuedTimerCompletion(Object state)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
public class TestController : ApiController
{
public HttpResponseMessage Post(Model model)
{
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// Create the queue client.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// Retrieve a reference to a queue.
CloudQueue queue = queueClient.GetQueueReference("webjobsqueue");
// Create the queue if it doesn't already exist.
queue.CreateIfNotExists();
// Create a message and add it to the queue.
CloudQueueMessage message = new CloudQueueMessage(JsonConvert.SerializeObject(new SimpleClass { SimpleStringProperty = Model.Value }));
queue.AddMessage(message);
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
class Program
{
static void Main(string[] args)
{
var host = new JobHost();
host.RunAndBlock();
}
public static void WaitForMessageInQueue([QueueTrigger("webjobsqueue")]
string message)
{
var simpleClass = JsonConvert.DeserializeObject<SimpleClass >(message);
Console.Out(simpleClass.SimpleStringProperty );
}
}
###There is a post in the MSDN Forum with the same problem but no solution WebJobs Feedback ###MSDN 论坛有帖子有同样问题但没有解决方案WebJobs 反馈
Not every sequence of bytes is valid UTF-8 text.并非每个字节序列都是有效的 UTF-8 文本。 If you're receiving a valid random Unicode/UTF-8 string, everything should work correctly.如果您收到一个有效的随机 Unicode/UTF-8 字符串,则一切都应该正常工作。 But if you're receiving random bytes (not UTF-8 text), this behavior is expected.但是,如果您收到随机字节(不是 UTF-8 文本),则会出现这种行为。 CloudQueueMessage, the Azure Storage SDK's API for dealing with queue messages, kindly validates that it has valid text before handing it back to you. CloudQueueMessage 是用于处理队列消息的 Azure 存储 SDK 的 API,在将其交还给您之前,请先验证它是否具有有效文本。 Apparently some of the other classes do not do that kind of validation and instead silently ignore invalid text.显然,其他一些类不进行这种验证,而是默默地忽略无效文本。
I'd suggest validating Model.Value in your Web API action to ensure it's valid Unicode text before adding the message to the queue.我建议在您的 Web API 操作中验证 Model.Value 以确保在将消息添加到队列之前它是有效的 Unicode 文本。 I'd suggest using the result from model.Value.Normalize(), which says it will throw if the string contains invalid Unicode data.我建议使用来自 model.Value.Normalize() 的结果,它表示如果字符串包含无效的 Unicode 数据,它将抛出。
I am using the latest version of the Webjob SDK and every thing work fine for me using your code:我正在使用最新版本的Webjob SDK,并且使用您的代码对我来说一切正常:
I've created a simple model:我创建了一个简单的模型:
public class SimpleClass
{
public string SimpleStringProperty { get; set; }
}
A class Function: A类功能:
public class Function
{
public void WaitForMessageInQueue([QueueTrigger("webjobsqueue")] string message)
{
Console.Out.WriteLine(message);
}
}
And here is my sample web job program:这是我的示例网络作业程序:
class Program
{
// Please set the following connection strings in app.config for this WebJob to run:
// AzureWebJobsDashboard and AzureWebJobsStorage
static void Main()
{
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("MyConnectionString"));
// Create the queue client.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
// Retrieve a reference to a queue.
CloudQueue queue = queueClient.GetQueueReference("webjobsqueue");
// Create the queue if it doesn't already exist.
queue.CreateIfNotExists();
// Create a message and add it to the queue.
CloudQueueMessage message = new CloudQueueMessage(JsonConvert.SerializeObject(new SimpleClass { SimpleStringProperty = "APA91bELkr6CyBmqLbWomwkI2zw_GkXGVsblYH60l4hERXw9ZkCcXufjJM_7IZXI5_Ry9aze6AhYRVzBfl6CYq0kxrdV4ViPkW5hK2Rd2HlsZCDfhnOc3PGLt_SzIMjfbMRug_eK_di2YbJTA6weczoTyb-dKuvnwg" }));
queue.AddMessage(message);
var host = new JobHost();
host.RunAndBlock();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.