Пример #1
0
        public ActionResult GetShortUrl(string codesStr)
        {
            var codes = GetCodes(codesStr);

            ConcurrentDictionary <int, string> dic = new ConcurrentDictionary <int, string>();
            List <Task>      tasks      = new List <Task>();
            List <Exception> exceptions = new List <Exception>();
            var totalCount    = codes.Length;
            var successCount  = 0;
            var finishedCount = 0;

            for (int i = 0; i < totalCount; i++)
            {
                var index = i;
                try
                {
                    var task = Senparc.Weixin.MP.AdvancedAPIs.UrlApi.ShortUrlAsync(Config.SenparcWeixinSetting.MpSetting.WeixinAppId, "long2short", codes[index])
                               .ContinueWith(weixinResult =>
                    {
                        dic[index] = weixinResult.Result.short_url;
                        successCount++;
                    })
                               .ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    exceptions.Add(ex);
                    dic[index] = "";
                }
                finally
                {
                    finishedCount++;
                }

                //tasks.Add(task);
            }

            //Task.WaitAll(tasks.ToArray(), TimeSpan.FromMinutes(1));
            var dt1 = SystemTime.Now;

            while (successCount < codes.Length && SystemTime.NowDiff(dt1).TotalSeconds < 60)
            {
                Thread.Sleep(1000);
            }

            var result = string.Join(Environment.NewLine, dic.OrderBy(z => z.Key).Select(z => z.Value));

            return(Json(new { result = result, totalCount = totalCount, successCount = successCount, errors = string.Join(" , ", exceptions.Select(z => z.Message).ToArray()) }));
        }
Пример #2
0
        public IApplicationBuilder UseMiddleware(IApplicationBuilder app)
        {
            var docDir    = Path.Combine(Senparc.Ncf.Core.Config.SiteConfig.WebRootPath, "NcfDocs\\cn\\docs\\doc\\");
            var assetsDir = Path.GetFullPath(Path.Combine(docDir, "..\\", "assets"));

            app.Map("/Docs", async builder =>
            {
                var indexHtmlFileDir  = Path.Combine(Senparc.Ncf.Core.Config.SiteConfig.WebRootPath, "NcfDocs\\cn\\docs\\assets\\");
                var indexHtmlFilePath = Path.Combine(indexHtmlFileDir, "index.html");

                if (!File.Exists(indexHtmlFilePath))
                {
                    using (var scope = app.ApplicationServices.CreateScope())
                    {
                        UpdateDocs updateDocs = new UpdateDocs(scope.ServiceProvider);
                        updateDocs.Run(new UpdateDocs_Parameters());

                        //等待更新
                        var dt1 = SystemTime.Now;
                        while (SystemTime.NowDiff(dt1) < TimeSpan.FromSeconds(10))
                        {
                            if (File.Exists(indexHtmlFilePath))
                            {
                                break;
                            }
                            await Task.Delay(1000);
                        }
                    }
                }

                builder.Use(async(context, next) =>
                {
                    context.Response.ContentType = "text/html; charset=utf-8";
                    using (var fs = new FileStream(indexHtmlFilePath, FileMode.Open))
                    {
                        await fs.CopyToAsync(context.Response.Body).ConfigureAwait(false);
                    }
                });
            });

            app.UseStaticFiles(new StaticFileOptions()
            {
                FileProvider = new PhysicalFileProvider(assetsDir),
                RequestPath  = new PathString("")
            });

            return(app);
        }
Пример #3
0
        public async Task <IActionResult> PostFile(string byStream = null)
        {
            var dt1            = SystemTime.Now;
            var filePath       = Path.GetFullPath("App_Data/cover.png");//也可以上传其他任意文件
            var fileDictionary = new Dictionary <string, string>();

            if (byStream != null)
            {
                //使用Stream传入,而不是文件名
                SenparcTrace.SendCustomLog("Post 文件信息", $"使用文件流放入 fileDictionary 中,并将修改文件名。");
                using (var fs = System.IO.File.OpenRead(filePath))
                {
                    var formFileData = new FormFileData(Path.GetFileName(filePath), fs);
                    formFileData.FileName   = $"changed-{formFileData.FileName}";//修改文件名
                    fileDictionary["image"] = formFileData.GetFileValue();
                }
            }
            else
            {
                SenparcTrace.SendCustomLog("Post 文件信息", $"使用文件物理地址放入 fileDictionary 中,保留原文件名。");
                fileDictionary["image"] = filePath;
            }

            var url    = "https://*****:*****@"<html>
<head>
<meta http-equiv=Content-Type content=""text/html;charset=utf-8"">
<title>CO2NET 文件 Post 测试 - {note}</title>
</head>
<body>
    <p>如果在下方看到《微信开发深度解析》图书封面,表示测试成功({note})。可通过 SenparcTrace 日志查看更多过调试信息日志。</p>
    <p>耗时:{timeCost.TotalMilliseconds} ms,平均:{averageCost} ms</p>
       <img src=""data:image/png; base64,{result}"" />
</body>
</html>";

            return(Content(html, "text/html"));
        }
Пример #4
0
        public void ThreadConfig(XncfThreadBuilder xncfThreadBuilder)
        {
            xncfThreadBuilder.AddThreadInfo(new Ncf.XncfBase.Threads.ThreadInfo(
                                                name: "定时备份",
                                                intervalTime: TimeSpan.FromSeconds(30),
                                                task: async(app, threadInfo) =>
            {
                try
                {
                    //SenparcTrace.SendCustomLog("执行调试", "DatabaseToolkit.Register.ThreadConfig");
                    threadInfo.RecordStory("开始检测并备份");

                    using (var scope = app.ApplicationServices.CreateScope())
                    {
                        var serviceProvider = scope.ServiceProvider;

                        //检测当前模块是否可用
                        XncfRegisterManager xncfRegisterManager = new XncfRegisterManager(serviceProvider);
                        var xncfIsValiable = await xncfRegisterManager.CheckXncfValiable(this);
                        if (!xncfIsValiable)
                        {
                            throw new NcfModuleException($"{this.MenuName} 模块当前不可用,跳过数据库自动备份轮询");
                        }

                        //初始化数据库备份方法
                        BackupDatabase backupDatabase = new BackupDatabase(serviceProvider);
                        //初始化参数
                        var backupParam     = new BackupDatabase.BackupDatabase_Parameters();
                        var dbConfigService = serviceProvider.GetService <ServiceBase <DbConfig> >();
                        var dbConfig        = await dbConfigService.GetObjectAsync(z => true);
                        var stopBackup      = false;
                        try
                        {
                            if (dbConfig != null && dbConfig.BackupCycleMinutes > 0 && !dbConfig.BackupPath.IsNullOrEmpty())
                            {
                                if (SystemTime.NowDiff(dbConfig.LastBackupTime) > TimeSpan.FromMinutes(dbConfig.BackupCycleMinutes))
                                {
                                    backupParam.Path = dbConfig.BackupPath;
                                    //await backupParam.LoadData(serviceProvider);
                                    //threadInfo.RecordStory("完成备份设置数据载入");
                                }
                                else
                                {
                                    stopBackup = true;
                                }
                            }
                            else
                            {
                                threadInfo.RecordStory("不需要备份,或没有设置备份周期/路径,已忽略本次备份计划");
                                stopBackup = true;    //不需要备份,或没有设置,返回
                            }
                        }
                        catch (Exception ex)
                        {
                            threadInfo.RecordStory($@"遇到异常,可能未配置数据库,已忽略本次备份计划。如需启动,请更新此模块到最新版本。
异常信息:{ex.Message}
{ex.StackTrace}");
                            stopBackup = true;    //可能没有配置数据库,返回
                        }

                        if (stopBackup)
                        {
                            return;
                        }


                        //执行备份方法
                        threadInfo.RecordStory("备份开始:" + backupParam.Path);
                        var result = backupDatabase.Run(backupParam);
                        if (!result.Success)
                        {
                            threadInfo.RecordStory("执行备份发生异常:" + result.Message);
                            throw new Exception("执行备份发生异常");
                        }

                        dbConfig.RecordBackupTime();
                        await dbConfigService.SaveObjectAsync(dbConfig);

                        threadInfo.RecordStory("完成数据库自动备份:" + result.Message);
                        SenparcTrace.SendCustomLog("完成数据库自动备份", backupParam.Path);
                    }
                }
                catch (NcfModuleException ex)
                {
                    throw;
                }
                catch
                {
                    throw;
                }
                finally
                {
                    threadInfo.RecordStory("检测并备份结束");
                }
            },
                                                exceptionHandler: ex =>
            {
                SenparcTrace.SendCustomLog("DatabaseToolkit", $@"{ex.Message}
{ex.StackTrace}
{ex.InnerException?.StackTrace}");
                return(Task.CompletedTask);
            }));
        }
Пример #5
0
        public void ConvertTest()
        {
            var jsonStr = @"{
  ""UserName"": ""FromUserName(OpenId)"",
  ""LastActiveTime"": ""2019-09-24T15:17:54.3197922+00:00"",
  ""ThisActiveTime"": ""2019-09-23T07:17:59.6691421+00:00"",
  ""RequestMessages"": [
    {
      ""MsgType"": 0,
      ""Content"": ""天气"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047906563632900,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:14:06+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""天气"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047906563642900,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:14:08+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""天气"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047906563652900,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:14:08+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""天气"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047906563662800,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:14:08+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""天气"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047906563672800,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:14:08+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""天气"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047906563682800,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:14:10+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""1234"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047910625007590,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:17:49+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""1234"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047910625017600,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:17:53+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""1234"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047910625027600,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:17:54+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""天气"",
      ""bizmsgmenuid"": """",
      ""MsgId"": 637047910625037600,
      ""Encrypt"": """",
      ""ToUserName"": ""ToUserName"",
      ""FromUserName"": ""FromUserName(OpenId)"",
      ""CreateTime"": ""2019-09-22T23:17:59+08:00""
    }
  ],
  ""ResponseMessages"": [
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:天气\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:13:22 【Text】天气\r\n23:13:21 【Text】天气\r\n23:13:20 【Text】天气\r\n23:11:13 【Text】天气\r\n23:11:05 【Text】12345\r\n23:08:32 【Text】苏州\r\n23:07:06 【Text】天气\r\n23:04:51 【Text】111222\r\n23:03:31 【Text】111222\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:13:24.8832361+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:天气\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:13:24 【Text】天气\r\n23:13:22 【Text】天气\r\n23:13:21 【Text】天气\r\n23:13:20 【Text】天气\r\n23:11:13 【Text】天气\r\n23:11:05 【Text】12345\r\n23:08:32 【Text】苏州\r\n23:07:06 【Text】天气\r\n23:04:51 【Text】111222\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:14:06.8772982+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:天气\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:14:06 【Text】天气\r\n23:13:24 【Text】天气\r\n23:13:22 【Text】天气\r\n23:13:21 【Text】天气\r\n23:13:20 【Text】天气\r\n23:11:13 【Text】天气\r\n23:11:05 【Text】12345\r\n23:08:32 【Text】苏州\r\n23:07:06 【Text】天气\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:14:08.1252882+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:天气\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:14:08 【Text】天气\r\n23:14:06 【Text】天气\r\n23:13:24 【Text】天气\r\n23:13:22 【Text】天气\r\n23:13:21 【Text】天气\r\n23:13:20 【Text】天气\r\n23:11:13 【Text】天气\r\n23:11:05 【Text】12345\r\n23:08:32 【Text】苏州\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:14:08.7938944+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:天气\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:06 【Text】天气\r\n23:13:24 【Text】天气\r\n23:13:22 【Text】天气\r\n23:13:21 【Text】天气\r\n23:13:20 【Text】天气\r\n23:11:13 【Text】天气\r\n23:11:05 【Text】12345\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:14:09.414496+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:天气\r\n\r\n您刚才还发送了如下消息(10/1):\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:06 【Text】天气\r\n23:13:24 【Text】天气\r\n23:13:22 【Text】天气\r\n23:13:21 【Text】天气\r\n23:13:20 【Text】天气\r\n23:11:13 【Text】天气\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:14:09.9626979+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:天气\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:06 【Text】天气\r\n23:13:24 【Text】天气\r\n23:13:22 【Text】天气\r\n23:13:21 【Text】天气\r\n23:13:20 【Text】天气\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:14:10.2830586+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:1234\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:14:10 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:06 【Text】天气\r\n23:13:24 【Text】天气\r\n23:13:22 【Text】天气\r\n23:13:21 【Text】天气\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:17:50.6362189+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:1234\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:17:49 【Text】1234\r\n23:14:10 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:06 【Text】天气\r\n23:13:24 【Text】天气\r\n23:13:22 【Text】天气\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:17:53.8077989+08:00""
    },
    {
      ""MsgType"": 0,
      ""Content"": ""您刚才发送了文字信息:1234\r\n\r\n您刚才还发送了如下消息(10/0):\r\n23:17:53 【Text】1234\r\n23:17:49 【Text】1234\r\n23:14:10 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:08 【Text】天气\r\n23:14:06 【Text】天气\r\n23:13:24 【Text】天气\r\n\r\n\r\n如果您在3分钟内连续发送消息,记录将被自动保留(当前设置:最多记录10条)。过期后记录将会自动清除。\r\n\r\n\r\n您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。\r\nSDK官方地址:https://sdk.weixin.senparc.com\r\n"",
      ""ToUserName"": ""FromUserName(OpenId)"",
      ""FromUserName"": ""ToUserName"",
      ""CreateTime"": ""2019-09-22T23:17:54.3355697+08:00""
    }
  ],
  ""MaxRecordCount"": 10,
  ""StorageDataTypeName"": ""System.Int32"",
  ""StorageData"": 0,
  ""ExpireMinutes"": null,
  ""AppStoreState"": 2,
  ""CurrentAppDataItem"": {
    ""Name"": ""查天气"",
    ""Id"": ""3"",
    ""Note"": null,
    ""Version"": ""0.1.0"",
    ""ExpireTime"": 1571832729,
    ""ExpireDateTime"": ""2019-10-23T20:12:09+08:00"",
    ""MessageEnterWord"": ""天气"",
    ""MessageExitWord"": ""退出"",
    ""MessageKeywords"": null,
    ""MessageKeepTime"": 1
  }
}";

            var dt1        = SystemTime.Now;
            var jsonResult = JsonConvert.DeserializeObject <CustomMessageContext>(jsonStr, new MessageContextJsonConverter <CustomMessageContext, RequestMessageBase, ResponseMessageBase>());

            Console.WriteLine(SystemTime.NowDiff(dt1).TotalMilliseconds + "ms");
            Assert.IsNotNull(jsonResult);
            Console.WriteLine(jsonResult);
        }
Пример #6
0
        /// <summary>
        /// 创建动态 WebApi
        /// </summary>
        public async Task <int> BuildWebApi(IGrouping <string, KeyValuePair <string, ApiBindInfo> > apiBindGroup)
        {
            var category = apiBindGroup.Key;
            var dt1      = SystemTime.Now;

            WriteLog("", true);
            WriteLog($"==== Begin BuildWebApi for {category} ====", true);

            if (apiBindGroup.Count() == 0 || !ApiAssemblyNames.ContainsKey(category))
            {
                WriteLog($"apiBindGroup 不存在可用对象: {category}");
                return(0);
            }

            var assembleName = ApiAssemblyNames[category];

            #region 动态创建程序集

            var dynamicAssembly = BuildDynamicAssembly(assembleName, apiBindGroup);

            #endregion

            //TODO:开放所有类型

            var apiBindFilterList = apiBindGroup.Where(z =>                                //!z.Value.GlobalName.EndsWith("Async")
                                                                                           //&& z.Value.MethodInfo.ReturnType != typeof(Task<>)
                                                                                           //&&
                                                       z.Value.MethodInfo.ReturnType != typeof(void) &&
                                                       !z.Value.MethodInfo.IsGenericMethod //SemanticApi.SemanticSend 是泛型方法

                                                                                           //临时过滤 IEnumerable 对象   —— Jeffrey Su 2021.06.17
                                                       && !z.Value.MethodInfo.GetParameters().Any(z =>
                                                                                                  z.IsOut ||
                                                                                                  z.ParameterType.Name.Contains("IEnumerable") ||
                                                                                                  z.ParameterType.Name.Contains("IList`1")))
                                    .OrderBy(z => z.Value.GlobalName)
                                    .ToArray();

            //把 CommonApi 提前到头部
            //Func<KeyValuePair<string, ApiBindInfo>, bool> funcCommonApi = z => z.Value.ApiBindAttribute.Name.StartsWith("CommonApi.");
            //var commonApiList = filterList.Where(z => funcCommonApi(z)).ToList();
            //filterList.RemoveAll(z => funcCommonApi(z));
            //filterList.InsertRange(0, commonApiList);

            int apiIndex = 0;
            ConcurrentDictionary <string, string> apiMethodName = new ConcurrentDictionary <string, string>();

            List <Task> taskList = new List <Task>();

            //预分配每个线程需要领取的任务(索引范围)
            var apiFilterMaxIndex = apiBindFilterList.Length - 1;                      //最大索引
            var avgBlockCount     = (int)((apiBindFilterList.Length - 1) / TaskCount); //每个线程(块)领取的平均数量
            var lastEndIndex      = -1;                                                //上一个块的结束索引

            for (int taskIndex = 0; taskIndex < TaskCount; taskIndex++)
            {
                if (lastEndIndex >= apiFilterMaxIndex)
                {
                    break;//已经排满,终止
                }

                var blockStart = Math.Min(lastEndIndex + 1, apiFilterMaxIndex); //当前块起始索引
                var blockEnd   = 0;                                             //当前快结束索引
                if (taskIndex == TaskCount - 1 ||                               /*最后一个快,一直分配到最后(解决余数问题)*/
                    avgBlockCount == 0 /*如果API总数比线程数还要少,则只够一个模块*/)
                {
                    blockEnd = apiFilterMaxIndex;//
                }
                else
                {
                    blockEnd = Math.Min(blockStart + avgBlockCount, apiFilterMaxIndex); //非最后一个快,取平均数量
                }
                lastEndIndex = blockEnd;                                                //记录当前快位置

                var apiTask = Task.Factory.StartNew(async() =>
                {
                    Range blockRange     = blockStart..(blockEnd + 1);
                    var apiBindInfoBlock = apiBindFilterList[blockRange];//截取一段,分配给当前任务

                    apiIndex++;

                    #region 创建 API 方法

                    await BuildApiMethodForOneThread(apiBindGroup, apiBindInfoBlock, apiMethodName, dynamicAssembly.ControllerKeyName, dynamicAssembly.Tb,
                                                     dynamicAssembly.FbServiceProvider, apiIndex);

                    #endregion
                });
                taskList.Add(apiTask.Unwrap());
            }

            await Task.WhenAll(taskList);

            WriteLog("Api Task Count:" + taskList.Count, true);

            TypeInfo objectTypeInfo = dynamicAssembly.Tb.CreateTypeInfo();
            var      myType         = objectTypeInfo.AsType();

            WriteLog($"\t create type:  {myType.Namespace} - {myType.FullName}");

            //WeixinApiAssembly = myType.Assembly;//注意:此处会重复赋值相同的对象,不布偶股影响效率

            ApiAssemblyCollection[category] = dynamicAssembly.Mb.Assembly;//储存程序集

            var timeCost = SystemTime.NowDiff(dt1);

            WriteLog($"==== Finish BuildWebApi for {category} / Total Time: {timeCost.TotalMilliseconds:###,###} ms ====");
            WriteLog("");

            return(apiMethodName.Count);
        }
Пример #7
0
        public ActionResult Index(string codesStr)
        {
            var codes = GetCodes(codesStr);

            var dt0 = SystemTime.Now;

            //QrCode 根目录
            var qrCodeDir = Path.Combine(CO2NET.Config.RootDictionaryPath, "App_Data", "QrCode");

            if (!Directory.Exists(qrCodeDir))
            {
                Directory.CreateDirectory(qrCodeDir);
            }

            //定义文件名和路径
            var tempId              = SystemTime.Now.ToString("yyyy-MM-dd-HHmmss"); //本次生成唯一Id
            var tempDirName         = $"{tempId}_{Guid.NewGuid().ToString("n")}";   //临时文件夹名
            var tempZipFileName     = $"{tempDirName}.zip";                         //临时压缩文件名
            var tempZipFileFullPath = Path.Combine(qrCodeDir, tempZipFileName);     //临时压缩文件完整路径
            var tempDir             = Path.Combine(qrCodeDir, tempDirName);

            Directory.CreateDirectory(tempDir);//创建临时目录

            //说明文件
            var readmeFile = Path.Combine(qrCodeDir, "readme.txt");

            System.IO.File.Copy(readmeFile, Path.Combine(tempDir, "readme.txt"));

            //便利所有二维码内容
            var i = 0;

            foreach (var code in codes)
            {
                if (code.IsNullOrEmpty())
                {
                    continue; //过滤为空的段落
                }
                i++;          //计数器


                var finalCode = code.Length > 100 ? code.Substring(0, 100) : code;//约束长度

                //二维码生成开始
                BitMatrix bitMatrix;//定义像素矩阵对象
                bitMatrix = new MultiFormatWriter().encode(finalCode, BarcodeFormat.QR_CODE /*条码或二维码标准*/, 600 /*宽度*/, 600 /*高度*/);
                var bw = new ZXing.BarcodeWriterPixelData();

                var pixelData = bw.Write(bitMatrix);
                var bitmap    = new System.Drawing.Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);//预绘制32bit标准的位图片

                var bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height) /*绘制矩形区域及偏移量*/,
                                                 System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
                try
                {
                    //假设位图的 row stride = 4 字节 * 图片的宽度
                    System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length);
                }
                finally
                {
                    bitmap.UnlockBits(bitmapData);//从内存 Unlock bitmap 对象
                }
                //二维码生成结束

                var fileName = Path.Combine(tempDir, $"{i}.jpg");//二维码文件名

                //保存二维码
                var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
                {
                    bitmap.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png);
                    fileStream.Close();//一定要关闭文件流
                }
            }
            SenparcTrace.SendCustomLog("二维码生成结束", $"耗时:{SystemTime.DiffTotalMS(dt0)} ms,临时文件:{tempZipFileFullPath}");//记录日志

            var dt1 = SystemTime.Now;

            while (Directory.GetFiles(tempDir).Length < i + 1 /* readme.txt */ && SystemTime.NowDiff(dt1) < TimeSpan.FromSeconds(30) /*最多等待时间*/)
            {
                Thread.Sleep(1000);//重试等待时间
            }

            ZipFile.CreateFromDirectory(tempDir, tempZipFileFullPath, CompressionLevel.Fastest, false);//创建压缩文件

            var dt2 = SystemTime.Now;

            while (SystemTime.NowDiff(dt2) < TimeSpan.FromSeconds(10) /*最多等待时间*/)
            {
                FileStream fs = null;
                try
                {
                    fs = new FileStream(tempZipFileFullPath, FileMode.Open, FileAccess.Read, FileShare.None);
                }
                catch
                {
                    Thread.Sleep(500);
                    continue;
                }

                if (fs != null)
                {
                    return(File(fs, "application/x-zip-compressed", $"SenparcQrCode_{tempId}.zip"));
                    //TODO:删除临时文件
                }
            }

            return(Content("打包文件失败!"));
        }
Пример #8
0
        public void DistributedCacheTest(Func <IBaseObjectCacheStrategy> cacheStrategy)
        {
            //强制使用本地缓存
            CacheStrategyFactory.RegisterObjectCacheStrategy(cacheStrategy);

            Console.WriteLine($"当前使用缓存:{CacheStrategyFactory.GetObjectCacheStrategyInstance().GetType().FullName}");

            //清空缓存
            var globalMessageContext = new GlobalMessageContext <CustomMessageContext, RequestMessageBase, ResponseMessageBase>();

            globalMessageContext.Restore();


            //第一次请求
            var dt1                   = SystemTime.Now;
            var doc                   = XDocument.Parse(textRequestXml.FormatWith("TNT2", CO2NET.Helpers.DateTimeHelper.GetUnixDateTime(SystemTime.Now.UtcDateTime), SystemTime.Now.Ticks));
            var messageHandler        = new CustomMessageHandler(doc, postModel);
            var currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();

            Assert.AreEqual(1, currentMessageContext.RequestMessages.Count);//初始化之后,RequestMessage 已经被记录到上下文中
            Assert.AreEqual(0, currentMessageContext.ResponseMessages.Count);

            messageHandler.Execute();
            Console.WriteLine($"第 1 次请求耗时:{SystemTime.NowDiff(dt1).TotalMilliseconds} ms");

            currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();

            Assert.AreEqual(1, currentMessageContext.RequestMessages.Count);
            Assert.AreEqual(0, currentMessageContext.ResponseMessages.Count);//默认使用异步ResponseMessage写入,有延迟(有时队列速度太快,也会执行到此处时已经写入,结果为1)

            //回复消息记录可以使用队列,对时间不敏感,因此需要等待队列完成记录
            Thread.Sleep(500);
            currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();
            Assert.AreEqual(1, currentMessageContext.ResponseMessages.Count);//默认使用异步ResponseMessage写入,有延迟

            Console.WriteLine(currentMessageContext.ResponseMessages.Last().GetType());
            Console.WriteLine(currentMessageContext.ResponseMessages.Last().ToJson());

            //测试 StorageData
            Assert.AreEqual(1, currentMessageContext.StorageData);

            var lastResponseMessage = currentMessageContext.ResponseMessages.Last() as ResponseMessageText;

            Assert.IsNotNull(lastResponseMessage);
            Assert.AreEqual("来自单元测试:TNT2", lastResponseMessage.Content);


            //第二次请求

            var dt2 = SystemTime.Now;

            doc            = XDocument.Parse(textRequestXml.FormatWith("TNT3", CO2NET.Helpers.DateTimeHelper.GetUnixDateTime(SystemTime.Now.UtcDateTime), SystemTime.Now.Ticks));
            messageHandler = new CustomMessageHandler(doc, postModel)
            {
                RecordResponseMessageSync = true //设置同步写入 ResponseMessage
            };

            currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();
            Assert.AreEqual(2, currentMessageContext.RequestMessages.Count);
            Assert.AreEqual(1, currentMessageContext.ResponseMessages.Count);

            messageHandler.Execute();
            Console.WriteLine($"第 2 次请求耗时:{SystemTime.NowDiff(dt2).TotalMilliseconds} ms");

            currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();
            Assert.AreEqual(2, currentMessageContext.RequestMessages.Count);
            Assert.AreEqual(2, currentMessageContext.ResponseMessages.Count);//同步写入 ResponseMessage,没有延迟

            lastResponseMessage = currentMessageContext.ResponseMessages.Last() as ResponseMessageText;
            Assert.IsNotNull(lastResponseMessage);
            Assert.AreEqual("来自单元测试:TNT3", lastResponseMessage.Content);


            //测试去重
            var dt3 = SystemTime.Now;

            messageHandler = new CustomMessageHandler(doc, postModel)
            {
                RecordResponseMessageSync = true //设置同步写入 ResponseMessage
            };                                   //使用和上次同样的请求

            currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();
            Assert.AreEqual(2, currentMessageContext.RequestMessages.Count);
            Assert.AreEqual(2, currentMessageContext.ResponseMessages.Count);

            messageHandler.Execute();
            Console.WriteLine($"第 3 次请求耗时:{SystemTime.NowDiff(dt3).TotalMilliseconds} ms");

            //没有变化
            currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();
            Assert.AreEqual(2, currentMessageContext.RequestMessages.Count);
            Assert.AreEqual(2, currentMessageContext.ResponseMessages.Count);
            lastResponseMessage = currentMessageContext.ResponseMessages.Last() as ResponseMessageText;
            Assert.IsNotNull(lastResponseMessage);
            Assert.AreEqual("来自单元测试:TNT3", lastResponseMessage.Content);


            //测试最大纪录储存

            Console.WriteLine("==== 循环测试开始 ====");
            for (int i = 0; i < 15; i++)
            {
                var dt4 = SystemTime.Now;
                doc = XDocument.Parse(textRequestXml.FormatWith($"循环测试-{i}", CO2NET.Helpers.DateTimeHelper.GetUnixDateTime(SystemTime.Now.UtcDateTime) + i, SystemTime.Now.Ticks));
                var maxRecordCount = 10;
                messageHandler = new CustomMessageHandler(doc, postModel, maxRecordCount)
                {
                    RecordResponseMessageSync = true //设置同步写入 ResponseMessage
                };                                   //使用和上次同样的请求
                //messageHandler.GlobalMessageContext.MaxRecordCount = 10;//在这里设置的话,Request已经插入了,无法及时触发删除多余消息的过程
                messageHandler.Execute();

                currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();
                Assert.AreEqual(i < 7 ? i + 3 : 10, currentMessageContext.RequestMessages.Count);
                Assert.AreEqual(i < 7 ? i + 3 : 10, currentMessageContext.ResponseMessages.Count);

                Console.WriteLine($"第 {i + 1} 次循环测试请求耗时:{SystemTime.NowDiff(dt4).TotalMilliseconds} ms");
            }
            Console.WriteLine("==== 循环测试结束 ====");


            //清空
            messageHandler.GlobalMessageContext.Restore();
            currentMessageContext = messageHandler.GetCurrentMessageContext().GetAwaiter().GetResult();
            Assert.AreEqual(0, currentMessageContext.RequestMessages.Count);

            //回复消息记录可以使用队列,对时间不敏感,因此需要等待队列完成记录
            Thread.Sleep(300);
            Assert.AreEqual(0, currentMessageContext.ResponseMessages.Count);

            Console.WriteLine();
        }
Пример #9
0
        public async Task <IActionResult> RunTest()
        {
            var sb = new StringBuilder();

            try
            {
                var containerCacheStrategy     = ContainerCacheStrategyFactory.GetContainerCacheStrategyInstance() /*.ContainerCacheStrategy*/;
                var currentSystemCacheStrategy = containerCacheStrategy.BaseCacheStrategy();
                sb.AppendFormat($"当前系统缓存策略:{containerCacheStrategy.GetType().Name}<br /><br />");
                var currentSystemContainerCacheStrategy = ContainerCacheStrategyFactory.GetContainerCacheStrategyInstance();
                sb.AppendFormat($"当前系统容器缓存(领域缓存)策略:{currentSystemContainerCacheStrategy.GetType().Name}<br /><br />");


                var caches = new Dictionary <IBaseObjectCacheStrategy, IContainerCacheStrategy> {
                    { LocalObjectCacheStrategy.Instance, LocalContainerCacheStrategy.Instance }
                };
                try
                {
                    caches[RedisObjectCacheStrategy.Instance] = RedisContainerCacheStrategy.Instance;
                }
                catch (Exception)
                {
                    sb.Append("==== 当前系统未配置 Reis,跳过 Redis测试 ====<br /><br />");
                }

                var cacheExpire = TimeSpan.FromSeconds(1);

                foreach (var cacheSet in caches)
                {
                    bool testSuccess           = false;
                    TestContainerBag1 cacheBag = null;
                    var baseCache      = cacheSet.Key;
                    var containerCache = cacheSet.Value;
                    sb.AppendFormat($"==== 开始指定调用缓存策略:{baseCache.GetType().Name} ====<br /><br />");

                    sb.Append($"----- 测试写入(先异步后同步) -----<br />");
                    var shortBagKey = SystemTime.Now.ToString("yyyyMMdd-HHmmss") + "." + cacheExpire.GetHashCode();                   //创建不重复的Key
                    var finalBagKey = baseCache.GetFinalKey(ContainerHelper.GetItemCacheKey(typeof(TestContainerBag1), shortBagKey)); //获取最终缓存中的键
                    var bag         = new TestContainerBag1()
                    {
                        Key      = shortBagKey,
                        DateTime = SystemTime.Now
                    };
                    var dt1 = SystemTime.Now;
                    await baseCache.SetAsync(finalBagKey, bag, expiry : null, true);//不设置过期时间

                    sb.Append($"异步写入完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");

                    dt1 = SystemTime.Now;
                    baseCache.Set(finalBagKey, bag, expiry: null, true);//不设置过期时间
                    sb.Append($"同步写入完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");
                    sb.Append($"----- 写入测试完成 -----<br /><br />");

                    sb.Append($"----- 检查缓存读取(先同步后异步) -----<br />");


                    dt1      = SystemTime.Now;
                    cacheBag = baseCache.Get <TestContainerBag1>(finalBagKey, true);
                    sb.Append($"同步读取完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");

                    dt1      = SystemTime.Now;
                    cacheBag = await baseCache.GetAsync <TestContainerBag1>(finalBagKey, true);

                    testSuccess = cacheBag != null;
                    sb.Append($"异步读取完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");

                    testSuccess &= cacheBag != null && cacheBag.DateTime == bag.DateTime && bag.Key == shortBagKey;
                    sb.Append($"----- 检查结果:{(testSuccess ? "成功" : "失败")} -----<br /><br />");


                    sb.Append($"----- 容器缓存(领域缓存)修改测试 -----<br />");
                    dt1 = SystemTime.Now;
                    cacheBag.DateTime = SystemTime.Now;
                    await TestContainer1.UpdateAsync(cacheBag, cacheExpire);//设置过期时间

                    sb.Append($"写入完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");

                    var dt2 = SystemTime.Now;
                    var containerResult1 = await TestContainer1.TryGetItemAsync <TestContainerBag1>(shortBagKey, z => z);

                    sb.Append($"使用 ContainerCacheStrategy 读取完成:{SystemTime.NowDiff(dt2).TotalMilliseconds.ToString("f4")} ms<br />");

                    dt2 = SystemTime.Now;
                    var containerResult2 = await baseCache.GetAsync <TestContainerBag1>(finalBagKey, true);

                    sb.Append($"使用 BaseContainerStrategy 读取完成:{SystemTime.NowDiff(dt2).TotalMilliseconds.ToString("f4")} ms<br />");

                    testSuccess = containerResult1 != null && containerResult2 != null && containerResult1.Key == containerResult2.Key && containerResult1.DateTime == containerResult2.DateTime;
                    sb.Append($"----- 测试结果:{(testSuccess ? "成功" : "失败")}(总耗时:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms) -----<br /><br />");

                    sb.Append($"----- 检查缓存过期 -----<br />");
                    var sleepTime = cacheExpire.Add(TimeSpan.FromMilliseconds(500));
                    sb.Append($"线程休眠:{sleepTime.TotalSeconds.ToString("f2")}s<br />");
                    await Task.Delay(sleepTime);

                    cacheBag = await baseCache.GetAsync <TestContainerBag1>(finalBagKey, true);

                    sb.Append($"----- 检查结果:{(cacheBag == null ? "成功" : "失败")} -----<br /><br />");

                    sb.Append($"----- 检查缓存删除 -----<br />");
                    await baseCache.UpdateAsync(finalBagKey, bag, cacheExpire, true);

                    cacheBag = await baseCache.GetAsync <TestContainerBag1>(finalBagKey, true);

                    testSuccess = cacheBag != null;
                    sb.Append($"写入待删除项目:{(cacheBag != null ? "成功" : "失败")}<br />");
                    dt1 = SystemTime.Now;
                    await baseCache.RemoveFromCacheAsync(finalBagKey, true);

                    sb.Append($"删除项目({SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms)<br />");
                    cacheBag = await baseCache.GetAsync <TestContainerBag1>(finalBagKey, true);

                    sb.Append($"----- 删除结果检查:{(cacheBag == null ? "成功" : "失败")} -----<br /><br /><br />");
                }
            }
            catch (Exception ex)
            {
                sb.Append($@"===== 发生异常:{ex.Message} =====<br />
{ex.StackTrace.ToString()}<br />
{ex.InnerException?.StackTrace.ToString()}<br />");
            }

            return(Content(sb.ToString()));
        }
Пример #10
0
        public async Task <IActionResult> RunTest(int id = 0)
        {
            var sb = new StringBuilder();

            try
            {
                //选择要测试的缓存类型
                IContainerCacheStrategy containerCacheStrategy;
                switch (id)
                {
                case 1:
                    containerCacheStrategy = Senparc.Weixin.Cache.Redis.RedisContainerCacheStrategy.Instance;
                    break;

                case 2:
                    containerCacheStrategy = Senparc.Weixin.Cache.CsRedis.RedisContainerCacheStrategy.Instance;
                    break;

                case -1:
                    containerCacheStrategy = ContainerCacheStrategyFactory.GetContainerCacheStrategyInstance();
                    break;

                default:
                    containerCacheStrategy = Senparc.Weixin.Cache.LocalContainerCacheStrategy.Instance;
                    break;
                }

                var baseCache = containerCacheStrategy.BaseCacheStrategy();
                sb.AppendFormat($"当前测试缓存策略:{baseCache.GetType().FullName}<br /><br />");
                var containerCache = ContainerCacheStrategyFactory.GetContainerCacheStrategyInstance();
                sb.AppendFormat($"当前测试容器缓存(领域缓存)策略:{containerCache.GetType().FullName}<br /><br />");

                var          cacheExpire = TimeSpan.FromSeconds(1);
                const string successTag  = "<span style=\"color:green\">成功</span>";
                const string faildTag    = "<span style=\"color:red\">失败</span>";

                bool testSuccess           = false;
                TestContainerBag1 cacheBag = null;

                sb.AppendFormat($"==== 开始指定调用缓存策略:{baseCache.GetType().FullName} ====<br /><br />");

                sb.Append($"----- 测试写入(先异步后同步) -----<br />");
                var shortBagKey = SystemTime.Now.ToString("yyyyMMdd-HHmmss") + "." + cacheExpire.GetHashCode();                   //创建不重复的Key
                var finalBagKey = baseCache.GetFinalKey(ContainerHelper.GetItemCacheKey(typeof(TestContainerBag1), shortBagKey)); //获取最终缓存中的键
                var bag         = new TestContainerBag1()
                {
                    Key      = shortBagKey,
                    DateTime = SystemTime.Now
                };
                var dt1 = SystemTime.Now;
                await baseCache.SetAsync(finalBagKey, bag, expiry : null, true);//不设置过期时间

                sb.Append($"异步写入完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");

                dt1 = SystemTime.Now;
                baseCache.Set(finalBagKey, bag, expiry: null, true);//不设置过期时间
                sb.Append($"同步写入完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");
                sb.Append($"----- 写入测试完成 -----<br /><br />");

                sb.Append($"----- 检查缓存读取(先同步后异步) -----<br />");


                dt1      = SystemTime.Now;
                cacheBag = baseCache.Get <TestContainerBag1>(finalBagKey, true);
                sb.Append($"同步读取完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");

                dt1      = SystemTime.Now;
                cacheBag = await baseCache.GetAsync <TestContainerBag1>(finalBagKey, true);

                testSuccess = cacheBag != null;
                sb.Append($"异步读取完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");

                testSuccess &= cacheBag != null && cacheBag.DateTime == bag.DateTime && bag.Key == shortBagKey;
                sb.Append($"----- 检查结果:{(testSuccess ? successTag : faildTag)} -----<br /><br />");


                sb.Append($"----- 容器缓存(领域缓存)修改测试 -----<br />");
                dt1 = SystemTime.Now;
                cacheBag.DateTime = SystemTime.Now;
                await TestContainer1.UpdateAsync(cacheBag, cacheExpire);//设置过期时间

                sb.Append($"写入完成:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms<br />");

                var dt2 = SystemTime.Now;
                var containerResult1 = await TestContainer1.TryGetItemAsync <TestContainerBag1>(shortBagKey, z => z);

                sb.Append($"使用 ContainerCacheStrategy 读取完成:{SystemTime.NowDiff(dt2).TotalMilliseconds.ToString("f4")} ms<br />");

                dt2 = SystemTime.Now;
                var containerResult2 = await baseCache.GetAsync <TestContainerBag1>(finalBagKey, true);

                sb.Append($"使用 BaseContainerStrategy 读取完成:{SystemTime.NowDiff(dt2).TotalMilliseconds.ToString("f4")} ms<br />");

                testSuccess = containerResult1 != null && containerResult2 != null && containerResult1.Key == containerResult2.Key && containerResult1.DateTime == containerResult2.DateTime;
                sb.Append($"----- 测试结果:{(testSuccess ? successTag : faildTag)}(总耗时:{SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms) -----<br /><br />");

                sb.Append($"----- 检查缓存过期 -----<br />");
                var sleepTime = cacheExpire.Add(TimeSpan.FromMilliseconds(500));
                sb.Append($"线程休眠:{sleepTime.TotalSeconds.ToString("f2")}s<br />");
                await Task.Delay(sleepTime);

                cacheBag = await baseCache.GetAsync <TestContainerBag1>(finalBagKey, true);

                sb.Append($"----- 检查结果:{(cacheBag == null ? successTag : faildTag)} -----<br /><br />");

                //sb.Append($"----- 检查缓存删除 -----<br />");
                //await baseCache.UpdateAsync(finalBagKey, bag, cacheExpire, true);
                //cacheBag = await baseCache.GetAsync<TestContainerBag1>(finalBagKey, true);
                //testSuccess = cacheBag != null;
                //sb.Append($"写入待删除项目:{(cacheBag != null ? successTag : faildTag)}<br />");
                //dt1 = SystemTime.Now;
                //await baseCache.RemoveFromCacheAsync(finalBagKey, true);
                //sb.Append($"删除项目({SystemTime.NowDiff(dt1).TotalMilliseconds.ToString("f4")} ms)<br />");
                //cacheBag = await baseCache.GetAsync<TestContainerBag1>(finalBagKey, true);
                //sb.Append($"----- 删除结果检查:{(cacheBag == null ? successTag : faildTag)} -----<br /><br /><br />");
            }
            catch (Exception ex)
            {
                sb.Append($@"===== 发生异常:{ex.Message} =====<br />
{ex.StackTrace.ToString()}<br />
{ex.InnerException?.StackTrace.ToString()}<br />");
            }

            return(Content(sb.ToString()));
        }
Пример #11
0
        public ActionResult Index(string codesStr)
        {
            var codes = codesStr.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            var i     = 0;

            //限制个数
            if (codes.Length > 200)
            {
                codes = codes.Take(100).ToArray();
            }

            var qrCodeDir = Path.Combine(CO2NET.Config.RootDictionaryPath, "App_Data", "QrCode");

            if (!Directory.Exists(qrCodeDir))
            {
                Directory.CreateDirectory(qrCodeDir);
            }

            //定义文件名和路径
            var tempId              = SystemTime.Now.ToString("yyyy-MM-dd-HHmmss");
            var tempDirName         = $"{tempId}_{Guid.NewGuid().ToString("n")}";
            var tempZipFileName     = $"{tempDirName}.zip";
            var tempZipFileFullPath = Path.Combine(qrCodeDir, tempZipFileName);
            var tempDir             = Path.Combine(qrCodeDir, tempDirName);

            Directory.CreateDirectory(tempDir);//创建临时目录

            var readmeFile = Path.Combine(qrCodeDir, "readme.txt");

            System.IO.File.Copy(readmeFile, Path.Combine(tempDir, "readme.txt"));

            //便利所有二维码内容
            foreach (var code in codes)
            {
                if (code.IsNullOrEmpty())
                {
                    continue;
                }
                i++;

                var finalCode = code.Length > 100 ? code.Substring(0, 100) : code;//约束长度

                BitMatrix bitMatrix;
                bitMatrix = new MultiFormatWriter().encode(finalCode, BarcodeFormat.QR_CODE, 600, 600);
                var bw = new ZXing.BarcodeWriterPixelData();

                var pixelData = bw.Write(bitMatrix);
                var bitmap    = new System.Drawing.Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

                var bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
                try
                {
                    // we assume that the row stride of the bitmap is aligned to 4 byte multiplied by the width of the image
                    System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length);
                }
                finally
                {
                    bitmap.UnlockBits(bitmapData);
                }

                var fileName = Path.Combine(tempDir, $"{i}.jpg");

                var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
                {
                    bitmap.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png);
                    fileStream.Close();
                }
            }
            SenparcTrace.SendCustomLog("二维码生成结束", tempZipFileFullPath);

            var dt1 = SystemTime.Now;

            while (Directory.GetFiles(tempDir).Length < i + 1 /* readme.txt */ && SystemTime.NowDiff(dt1) < TimeSpan.FromSeconds(30) /*最多等待时间*/)
            {
                Thread.Sleep(1000);
            }

            ZipFile.CreateFromDirectory(tempDir, tempZipFileFullPath, CompressionLevel.Fastest, false);

            var dt2 = SystemTime.Now;

            while (SystemTime.NowDiff(dt2) < TimeSpan.FromSeconds(10) /*最多等待时间*/)
            {
                FileStream fs = null;
                try
                {
                    fs = new FileStream(tempZipFileFullPath, FileMode.Open, FileAccess.Read, FileShare.None);
                }
                catch
                {
                    Thread.Sleep(500);
                    continue;
                }

                if (fs != null)
                {
                    return(File(fs /*$"~/App_Data/QrCode/{tempZipFileName}"*/ /*tempZipFileFullPath*/, "application/x-zip-compressed", $"SenparcQrCode_{tempId}.zip"));
                }
            }

            return(Content("打包文件失败!"));
        }