4

我已经为此工作了几天,并阅读了之前关于多线程和 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();
        }
    }
}
4

1 回答 1

2

上面的代码产生了太多的并发线程,我天真的节流方法Thread.Sleep()不足以限制线程数。

引入信号量(基本上是一种计算并发执行的线程数的机制)极大地解决了这个问题。我正在稳步增加并发限制和实例数,并且每小时已经超过 100 万。(实际代码生成随机长度数据 16-32K,奇数一个 ~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();
        }
    }
}
于 2013-06-26T14:19:46.087 回答