我已经开展了几天的工作,已经阅读了有关多线程和blob客户端的先前问题,并实施了他们的建议。
我已将问题提炼到下面。
没有生成错误,只是没有任何内容写入 threadtest 容器(已经存在)。有时一个blob被写入然后什么也没有。
如果我将睡眠时间增加到1秒,一切都很好。
代码的原因是对Azure的blob编写功能进行基准测试。 (我目前有8个单线程实例,每小时700,000个,但我相信如果能算出来的话,我可以更高一些)
using System;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
namespace ThreadedWriterTest
{
public class WorkerRole : RoleEntryPoint
{
private static CloudStorageAccount storageAccount;
public override void Run()
{
while (true)
{
Thread.Sleep(10);
Task.Factory.StartNew(()=> writeStuff());
}
}
private void writeStuff()
{
CloudBlobClient threadClient = storageAccount.CreateCloudBlobClient();
threadClient.GetBlobReference("threadtest/" + Guid.NewGuid().ToString()).UploadText("Hello " + Guid.NewGuid().ToString());
}
public override bool OnStart()
{
ServicePointManager.DefaultConnectionLimit = 12;
storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("XXX"));
return base.OnStart();
}
}
}
答案 0 :(得分:2)
上面的代码生成了太多的并发线程,我使用Thread.Sleep()
进行限制的天真方法不足以限制线程数。
引入信号量(基本上是一种计算并发执行多少线程的机制)可以大大解决这个问题。我正在稳步增加并发限制和实例数,并且已经超过每小时100万。 (实际代码生成随机长度数据16-32K,奇数为1~4MB - 4个实例,10个并发线程)
using System;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
namespace ThreadedWriterTest
{
public class WorkerRole : RoleEntryPoint
{
private static CloudStorageAccount storageAccount;
private static Semaphore semaphore = new Semaphore(3, 3);
public override void Run()
{
while (true)
{
semaphore.WaitOne();
Task.Factory.StartNew(()=> writeStuff());
}
}
private void writeStuff()
{
CloudBlobClient threadClient = storageAccount.CreateCloudBlobClient();
threadClient.GetBlobReference("threadtest/" + Guid.NewGuid().ToString()).UploadText("Hello " + Guid.NewGuid().ToString());
semaphore.Release();
}
public override bool OnStart()
{
ServicePointManager.DefaultConnectionLimit = 12;
storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("XXX"));
return base.OnStart();
}
}
}