fastdeploy部署多线程/进程paddle ocr(python flask框架 )
部署参考:https://github.com/PaddlePaddle/FastDeploy/blob/develop/tutorials/multi_thread/python/pipeline/README_CN.md
安装
cpu: pip install fastdeploy-python
gpu :pip install fastdeploy-gpu-python
#下载部署示例代码
git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy/tutorials/multi_thread/python/pipeline# 下载模型,图片和字典文件
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_infer.tar
tar xvf ch_PP-OCRv3_det_infer.tarwget https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_infer.tar
tar -xvf ch_ppocr_mobile_v2.0_cls_infer.tarwget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar
tar xvf ch_PP-OCRv3_rec_infer.tarwget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/doc/imgs/12.jpgwget https://gitee.com/paddlepaddle/PaddleOCR/raw/release/2.6/ppocr/utils/ppocr_keys_v1.txt
命令:
多线程
python multi_thread_process_ocr.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image_path xxx/xxx --device gpu --thread_num 3
多进程
python multi_thread_process_ocr.py --det_model ch_PP-OCRv3_det_infer --cls_model ch_ppocr_mobile_v2.0_cls_infer --rec_model ch_PP-OCRv3_rec_infer --rec_label_file ppocr_keys_v1.txt --image_path xxx/xxx --device gpu --use_multi_process True --process_num 3
问题
多进程图片分配有bug
文件:multi_thread_process_ocr.py
原始代码:270行
修改为如下,去掉1
ModuleNotFoundError: No module named ‘example’
因为安装包不对,fastdeploy与fastdeploy-python不是同一个包
CUDA error(3), initialization error.
----------------------Error Message Summary:----------------------ExternalError: CUDA error(3), initialization error. [Hint: Please search for the error code(3) on website (https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__TYPES.html#group__CUDART__TYPES_1g3f51e3575c2178246db0a94a430e0038) to get Nvidia's official solution and advice about CUDA Error.] (at /home/fastdeploy/develop/paddle_build/v0.0.0/Paddle/paddle/phi/backends/gpu/cuda/cuda_info.cc:251)
参考:
PaddlePaddle——问题解决:使用Python multiprocessing时报错:CUDA error(3), initialization error.
https://github.com/PaddlePaddle/PaddleDetection/issues/2241
paddle 相关模块只在方法里面引用,要在多进程外有 import
这些模块
flask部署
发送列表类型的图片base64编码,返回列表类型的字符串
注意server端文件放在FastDeploy/tutorials/multi_thread/python/pipeline目录下
创建server端
from threading import Threadimport cv2
import os
from multiprocessing import Pool
import sysimport fastdeploy as fd
import numpy as np
import base64
from PIL import Image
from io import BytesIO
from sqlalchemy import create_engine, textfrom flask import Flask, request, jsonify
import argparse
import ast# watch -n 0.1 nvidia-smidef parse_arguments():parser = argparse.ArgumentParser()parser.add_argument("--det_model",# required=True,type=str,default='ch_PP-OCRv3_det_infer',help="Path of Detection model of PPOCR.")parser.add_argument("--cls_model",# required=True,type=str,default='ch_ppocr_mobile_v2.0_cls_infer',help="Path of Classification model of PPOCR.")parser.add_argument("--rec_model",# required=True,type=str,default='ch_PP-OCRv3_rec_infer',help="Path of Recognization model of PPOCR.")parser.add_argument("--rec_label_file",# required=True,type=str,default='ppocr_keys_v1.txt',help="Path of Recognization model of PPOCR.")# parser.add_argument(# "--image_path",# type=str,# required=True,# help="The directory or path or file list of the images to be predicted."# )parser.add_argument("--device",type=str,default='gpu', # cpuhelp="Type of inference device, support 'cpu', 'kunlunxin' or 'gpu'.")parser.add_argument("--backend",type=str,default="default",help="Type of inference backend, support ort/trt/paddle/openvino, default 'openvino' for cpu, 'tensorrt' for gpu")parser.add_argument("--device_id",type=int,default=0,help="Define which GPU card used to run model.")parser.add_argument("--cpu_thread_num",type=int,default=9,help="Number of threads while inference on CPU.")parser.add_argument("--cls_bs",type=int,default=1,help="Classification model inference batch size.")parser.add_argument("--rec_bs",type=int,default=6,help="Recognition model inference batch size")parser.add_argument("--thread_num", type=int, default=1, help="thread num")parser.add_argument("--use_multi_process",type=ast.literal_eval,default=True,help="Wether to use multi process.")parser.add_argument("--process_num", type=int, default=5, help="process num")return parser.parse_args()def get_image_list(image_path):image_list = []if os.path.isfile(image_path):image_list.append(image_path)# load image in a directoryelif os.path.isdir(image_path):for root, dirs, files in os.walk(image_path):for f in files:image_list.append(os.path.join(root, f))else:raise FileNotFoundError('{} is not found. it should be a path of image, or a directory including images.'.format(image_path))if len(image_list) == 0:raise RuntimeError('There are not image file in `--image_path`={}'.format(image_path))return image_listdef build_option(args):option = fd.RuntimeOption()if args.device.lower() == "gpu":option.use_gpu(args.device_id)option.set_cpu_thread_num(args.cpu_thread_num)if args.device.lower() == "kunlunxin":option.use_kunlunxin()return optionif args.backend.lower() == "trt":assert args.device.lower() == "gpu", "TensorRT backend require inference on device GPU."option.use_trt_backend()elif args.backend.lower() == "pptrt":assert args.device.lower() == "gpu", "Paddle-TensorRT backend require inference on device GPU."option.use_trt_backend()option.enable_paddle_trt_collect_shape()option.enable_paddle_to_trt()elif args.backend.lower() == "ort":option.use_ort_backend()elif args.backend.lower() == "paddle":option.use_paddle_infer_backend()elif args.backend.lower() == "openvino":assert args.device.lower() == "cpu", "OpenVINO backend require inference on device CPU."option.use_openvino_backend()return optiondef load_model(args, runtime_option):# Detection模型, 检测文字框det_model_file = os.path.join(args.det_model, "inference.pdmodel")det_params_file = os.path.join(args.det_model, "inference.pdiparams")# Classification模型,方向分类,可选cls_model_file = os.path.join(args.cls_model, "inference.pdmodel")cls_params_file = os.path.join(args.cls_model, "inference.pdiparams")# Recognition模型,文字识别模型rec_model_file = os.path.join(args.rec_model, "inference.pdmodel")rec_params_file = os.path.join(args.rec_model, "inference.pdiparams")rec_label_file = args.rec_label_file# PPOCR的cls和rec模型现在已经支持推理一个Batch的数据# 定义下面两个变量后, 可用于设置trt输入shape, 并在PPOCR模型初始化后, 完成Batch推理设置cls_batch_size = 1rec_batch_size = 6# 当使用TRT时,分别给三个模型的runtime设置动态shape,并完成模型的创建.# 注意: 需要在检测模型创建完成后,再设置分类模型的动态输入并创建分类模型, 识别模型同理.# 如果用户想要自己改动检测模型的输入shape, 我们建议用户把检测模型的长和高设置为32的倍数.det_option = runtime_optiondet_option.set_trt_input_shape("x", [1, 3, 64, 64], [1, 3, 640, 640],[1, 3, 960, 960])# 用户可以把TRT引擎文件保存至本地#det_option.set_trt_cache_file(args.det_model + "/det_trt_cache.trt")global det_modeldet_model = fd.vision.ocr.DBDetector(det_model_file, det_params_file, runtime_option=det_option)cls_option = runtime_optioncls_option.set_trt_input_shape("x", [1, 3, 48, 10],[cls_batch_size, 3, 48, 320],[cls_batch_size, 3, 48, 1024])# 用户可以把TRT引擎文件保存至本地# cls_option.set_trt_cache_file(args.cls_model + "/cls_trt_cache.trt")global cls_modelcls_model = fd.vision.ocr.Classifier(cls_model_file, cls_params_file, runtime_option=cls_option)rec_option = runtime_optionrec_option.set_trt_input_shape("x", [1, 3, 48, 10],[rec_batch_size, 3, 48, 320],[rec_batch_size, 3, 48, 2304])# 用户可以把TRT引擎文件保存至本地#rec_option.set_trt_cache_file(args.rec_model + "/rec_trt_cache.trt")global rec_modelrec_model = fd.vision.ocr.Recognizer(rec_model_file,rec_params_file,rec_label_file,runtime_option=rec_option)# 创建PP-OCR,串联3个模型,其中cls_model可选,如无需求,可设置为Noneglobal ppocr_v3ppocr_v3 = fd.vision.ocr.PPOCRv3(det_model=det_model, cls_model=cls_model, rec_model=rec_model)# 给cls和rec模型设置推理时的batch size# 此值能为-1, 和1到正无穷# 当此值为-1时, cls和rec模型的batch size将默认和det模型检测出的框的数量相同ppocr_v3.cls_batch_size = cls_batch_sizeppocr_v3.rec_batch_size = rec_batch_sizedef predict(model, img_list):result_list = []# predict ppocr resultfor image in img_list:im = cv2.imread(image)result = model.predict(im)result_list.append(result)return result_listdef process_predict(image):# predict ppocr resultim = cv2.imread(image)result = ppocr_v3.predict(im)print(result)def process_predict_text(base64_str):image = base64_to_bgr(base64_str)result = ppocr_v3.predict(image)# print(result)return ''.join(result.text) #不能直接返回OCR对象序列化会失败def cv_show(img):'''展示图片@param img:@param name:@return:'''cv2.namedWindow('name', cv2.WINDOW_KEEPRATIO) # cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIOcv2.imshow('name', img)cv2.waitKey(0)cv2.destroyAllWindows()def base64_to_bgr(base64_str):base64_hex = base64.b64decode(base64_str)image = BytesIO(base64_hex)img = Image.open(image)if img.mode=='RGBA':width = img.widthheight = img.heightimg2 = Image.new('RGB', size=(width, height), color=(255, 255, 255))img2.paste(img, (0, 0), mask=img)image_array = np.array(img2)else:image_array = np.array(img)image = cv2.cvtColor(image_array, cv2.COLOR_RGB2BGR)return imageclass WrapperThread(Thread):def __init__(self, func, args):super(WrapperThread, self).__init__()self.func = funcself.args = args# self.result = self.func(*self.args)def run(self):self.result = self.func(*self.args)def get_result(self):return self.resultdef ocr_image_list(imgs_list):args = parse_arguments()# 对于三个模型,均采用同样的部署配置# 用户也可根据自行需求分别配置runtime_option = build_option(args)if args.use_multi_process:process_num = args.process_numwith Pool(process_num,initializer=load_model,initargs=(args, runtime_option)) as pool:#results = pool.map(process_predict_text, imgs_list)# pool.map(process_predict, imgs_list)# 进一步处理结果for i, result in enumerate(results):print(i, result)else:load_model(args, runtime_option)threads = []thread_num = args.thread_numimage_num_each_thread = int(len(imgs_list) / thread_num)# unless you want independent model in each thread, actually model.clone()# is the same as model when creating thead because of the existence of# GIL(Global Interpreter Lock) in python. In addition, model.clone() will consume# additional memory to store independent member variablesfor i in range(thread_num):if i == thread_num - 1:t = WrapperThread(predict,args=(ppocr_v3.clone(),imgs_list[i * image_num_each_thread:]))else:t = WrapperThread(predict,args=(ppocr_v3.clone(),imgs_list[i * image_num_each_thread:(i + 1) *image_num_each_thread])) # - 1threads.append(t)t.start()for i in range(thread_num):threads[i].join()for i in range(thread_num):for result in threads[i].get_result():print('thread:', i, ', result: ', result)@app.route('/ocr/submit', methods=['POST'])
def ocr():args = parse_arguments()process_num = 1#args.process_numruntime_option = build_option(args)data = request.get_json()# 获取 Base64 数据base64_str = data['img_base64']with Pool(process_num, initializer=load_model, initargs=(args, runtime_option)) as pool:results = pool.map(process_predict_text, base64_str)# 返回响应response = {'message': 'Data received', 'result': results}return jsonify(response)import json
import pandas as pd
import timeif __name__ == '__main__':app.run(host='192.168.xxx.xxx', port=5000)
client 端
import base64
import sysimport requests
import json
# 读取图像文件
with open('./pic/img.png', 'rb') as image_file:# 将图像文件内容读取为字节流image_data = image_file.read()# 将图像字节流进行 Base64 编码
img_base64 = base64.b64encode(image_data)data = {'img_base64': [img_base64.decode('utf-8')] }headers = {'Content-Type': 'application/json'
}response = requests.post("http://192.168.xxx.xxx:5000/ocr/submit", data=json.dumps(data),headers = headers)if response.status_code == 200:result = response.json()print(result['result'])
else:print('Error:', response.status_code)
相关文章:
fastdeploy部署多线程/进程paddle ocr(python flask框架 )
部署参考:https://github.com/PaddlePaddle/FastDeploy/blob/develop/tutorials/multi_thread/python/pipeline/README_CN.md 安装 cpu: pip install fastdeploy-python gpu :pip install fastdeploy-gpu-python #下载部署示例代码 git cl…...
【图论】拓扑排序
一.定义 拓扑排序是一种对有向无环图(DAG)进行排序的算法,使得图中的每个顶点在排序中都位于其依赖的顶点之后。它通常用于表示一些任务之间的依赖关系,例如在一个项目中,某些任务必须在其他任务之前完成。 拓扑排序的…...
自动化备份方案
背景说明 网上有很多教程,写的都是从零搭建一个什么什么,基本上都是从无到有的教程,但是,很少有文章提及搭建好之后如何备份,这次通过请教GitHub Copilot Chat,生成几个备份脚本,以备后用。 注…...
win11出现安全中心空白和IT管理员已限制对此应用的某些区域的访问
问题 windows安全中心服务被禁用 winr 输入services.msc 找到windows安全中心服务查看是否被禁用,改为启动,不可以改动看第三条 打开设置,找到应用—windows安全中心–终止–修复–重置 重启如果还是不行看第四条 家庭版系统需要打开gped…...
github实用指令(实验室打工人入门必备)
博主进入实验室啦,作为一只手残党决定在这里分享一些常用的github使用情景和操作指南来解救其他手残党。 内容随着情景增加实时更新。如果只有没几个内容说明场景不多(相信对手残党而言是再好不过的消息) 情景一:…...
6. 激活层
6.1 非线性激活 ① inplace为原地替换,若为True,则变量的值被替换。若为False,则会创建一个新变量,将函数处理后的值赋值给新变量,原始变量的值没有修改。 import torch from torch import nn from torch.nn import …...
AIGC ChatGPT 制作地图可视化分析
地图可视化分析是一种将数据通过地图的形式进行展示的方法,可以让人们更加直观、快速、准确的理解和分析数据。以下是地图可视化分析的一些主要好处: 加强数据理解:地图可视化可以将抽象的数字转化为直观的图形,帮助我们更好地理解复杂的数据集。 揭示地理模式:地理位置是…...
2023-08-24 LeetCode每日一题(统计参与通信的服务器)
2023-08-24每日一题 一、题目编号 1267. 统计参与通信的服务器二、题目链接 点击跳转到题目位置 三、题目描述 这里有一幅服务器分布图,服务器的位置标识在 m * n 的整数矩阵网格 grid 中,1 表示单元格上有服务器,0 表示没有。 如果两台…...
前端实习day35
今天是下早班的一天,下完班直接赶车回广州了,吐槽一下深圳站管理得真得差,候车厅小,人巨多,而且进站口的标识也很少,绕了好久才找到!下次再也不去了。 今天是改bug的一天,但是有半天…...
Linux安装jupyter notebook
1. Linux安装jupyter notebook 1.1 生成配置文件 这里在conda环境中安装。 jupyter notebook --generate-config --allow-root上面命令是生成配置文件,并且允许使用root用户运行。配置文件默认生成到~/.jupyter/jupyter_notebook_config.py。 具体解释如下&…...
【猿灰灰赠书活动 - 03期】- 【RHCSA/RHCE 红帽Linux认证学习指南(第7版) EX200 EX300】
说明:博文为大家争取福利,与清华大学出版社合作进行送书活动 图书:《RHCSA/RHCE 红帽Linux认证学习指南(第7版) EX200 & EX300》 一、好书推荐 图书介绍 《RHCSA/RHCE 红帽Linux认证学习指南(第7版) EX200 & E…...
当 Tubi 遇到 Ruby
有人说 Tubi 作为 RubyConf China 金牌赞助商,明明用极具吸引力的 Elixir 后端工程师岗位和高品质的 Elixir Meetup,“拐走了”一批又一批 Rubyist 投身于 Elixir 开发中,却依然让人想在 Tubi 展台前多停留一会儿。 为什么工程师、校友甚至 …...
【C++从0到王者】第二十四站:多态的底层原理
文章目录 前言一、虚函数表二、一道经典的例题三、深度剖析多态的条件之一:为什么必须是父类的指针或引用四、深度剖析多态的条件之二:为什么是虚函数的重写/覆盖?五、虚函数表的一些总结六、关于Func3的验证七、动态绑定与静态绑定八、总结 …...
Java从入门到精通24==》数据库、SQL基本语句、DDL语句
Java从入门到精通24》数据库、SQL基本语句、DDL语句 2023.8.27 文章目录 <center>Java从入门到精通24》数据库、SQL基本语句、DDL语句一、什么是数据库二、数据库的优缺点1、使用数据库的优点:2、使用数据库的缺点: 三、MySQL基本语句四、DDL语句 …...
学习ts(十)装饰器
定义 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上,是一种在不改变原类和使用继承的情况下,动态的扩展对象功能。 装饰器使用expression形式,其中expression必须…...
如何在 Opera 中启用DNS over HTTPS
DNS over HTTPS(基于HTTPS的DNS)是一种更安全的浏览方式,但大多数 Web 浏览器默认情况下不启用它。了解如何在 Opera 浏览器中启用该功能。 您可能不知道这一点,但您的网络浏览器并不像您希望的那样私密或安全。您会看到ÿ…...
STM32 F103C8T6学习笔记13:IIC通信—AHT10温湿度传感器模块
今日学习一下这款AHT10 温湿度传感器模块,给我的OLED手环添加上测温湿度的功能。 文章提供源码、测试工程下载、测试效果图。 目录 AHT10温湿度传感器: 特性: 连接方式: 适用场所范围: 程序设计: 设…...
QT基础使用:组件和代码关联(信号和槽)
自动关联 ui文件在设计环境下,能看到的组件可以使用鼠标右键选择“转到槽”就是开始组件和动作关联。 在自动关联这个过程中软件自动动作的部分 需要对前面头文件进行保存,才能使得声明的函数能够使用。为了方便,自动关联时先对所有文件…...
TCP最大连接数问题总结
最大TCP连接数量限制有:可用端口号数量、文件描述符数量、线程、内存、CPU等。每个TCP连接都需要以下资源,如图所示: 1、可用端口号限制 Q:一台主机可以有多少端口号?端口号与TCP连接?是否能修改&#x…...
【Docker】云原生利用Docker确保环境安全、部署的安全性、安全问题的主要表现和新兴技术产生
前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 云原生利用Docker确保环境安全、部署的…...
explain各个字段代表的意思
id:联表查询是每个表的读取顺序,数字越大越先被读取。相同就需要通过table字段判断select_type:查询类型或者是其他操作类型(PRIMARY、UNION、UNION RESULT等)table:正在访问哪个表partitions:匹…...
【已解决】Windows10 pip安装报错:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x98
环境:win10, Python3.9 在Pycharm安装YoloV5的依赖包时出现报错:UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x98 出现 ‘gbk’ codec can’t decode… 的报错一般是因为读取文件出现编码问题导致没法读取文件,因此可以在报错…...
goland 中的调试器 -- Evaluate
今天一个好朋友 找到我,问我关于goland中Evaluate 小计算器的使用方式,说实话,我在此之前也没用过这个东西,然后我就找一些相关文档,但是这类文档少的可怜,所以我就稍微研究一下,找找材料&#…...
你知道公司内部维基到底有哪些功能吗
维基指的是一种协作工作的平台,也就是开源的编辑系统。员工可以在企业维基里面进行存储、共享和协作之类的操作,将企业内部员工的知识共享聚集在一起。今天looklook将会详细讲讲公司内部维基具体到底有哪些功能,供大家参考。 公司内部维基的功…...
netdata监控服务器主机(包括Docker容器)
效果 Docker部署 创建挂载目录 mkdir -p /data/netdata/{netdatacache,netdatalib}docker运行 docker run -d --namenetdata \-p 19999:19999 \-v /data/netdata/netdatalib:/var/lib/netdata \-v /data/netdata/netdatacache:/var/cache/netdata \-v /etc/passwd:/host/etc…...
Mybatis学习|第一个Mybatis程序
1.创建一个数据库以及一个用户表,并插入三条数据用来测试 2.创建一个空的maven项目 在pom.xml中导入本次测试用到的三个依赖,mysql驱动、mybatis依赖、以及单元测试junit依赖 将这个 空的maven项目当成一个父项目,再创建一个空的maven子项目用…...
计算机网络MTU和MSS的区别
在计算机网络中,MTU代表最大传输单元(Maximum Transmission Unit),而MSS代表最大分节大小(Maximum Segment Size)。 1.MTU(最大传输单元): MTU是指在网络通信中&#x…...
redis学习笔记 - 进阶部分
文章目录 redis单线程如何处理并发的客户端,以及为何单线程快?redis的发展历程:redis单线程和多线程的体现:redis3.x单线程时代但性能很快的主要原因:redis4.x开始引入多线程:redis6/redis7引入多线程IO&am…...
SE5 - BM1684 人工智能边缘开发板入门指南 -- 模型转换、交叉编译、yolov5、目标追踪
介绍 我们属于SoC模式,即我们在x86主机上基于tpu-nntc和libsophon完成模型的编译量化与程序的交叉编译,部署时将编译好的程序拷贝至SoC平台(1684开发板/SE微服务器/SM模组)中执行。 注:以下都是在Ubuntu20.04系统上操…...
基于Java+SpringBoot+vue前后端分离英语知识应用网站设计实现
博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…...
西安网站建设网站建设/网站seo优化运营
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
单位建网站的详细步骤/推广策略包括哪些内容
(注意:遇到程序在弄懂之后一定要自己去敲,一定要自己去敲,一定要自己去敲) (注意:遇到程序在弄懂之后一定要自己去敲,一定要自己去敲,一定要自己去敲) (注意:遇到程序在弄懂之后一定要自己去敲&…...
php源码建站 一品资源/手游推广平台代理
本文通过列举出一些常见的实例来分析Python3.0与2.X版本的区别,是作者经验的总结,对于Python程序设计人员来说有不错的参考价值。具体如下:做为一个前端开发的码农,最近通过阅读最新版的《A byte of Python》并与老版本的《A byte…...
做一个网站怎么做/网店运营具体做什么
dymDemo dym 分布式开发框架 Demo 熔断 限流 事件总线(包括基于内存的、rabbitmq的) CQRS DDD 实例 随后更新dym 分布式开发框架 dym 是一个分布式开发框架,同时支持 .net core2.2 、.net frameworker4.6.1。1、运行Demo 第一步:启…...
甘肃住房建设厅网站/百度游戏
为了减少心脏搏动伪影对心脏大血管MRI图像的影响,一般采用心电门控技术,应用本法的FR时间决定于十二指肠全长约UF项不包括透视在骨关节诊断中的应用是头颈部肿瘤术前放疗的合适剂量为选出MRI不如CT的项目冠状动脉粥样硬化主要侵犯以下分支儿童短骨结核特…...
ic千库网/seo专员是指什么意思
首先感慨下 vivizhyy 现在正在看的这本书——《Flex 完全自学手册》,这本书会让你看后相当有自信心,因为一般你会发现里面的代码不是太 cuo 就是太冗余……好吧,拿书里面给出的单选控件与用户交互的例子来说,书里给的 ① 个解决方…...