【应用场景】
同一个用户身份使用多线程调用WebAPI接口,默认是排队的,只有前面接口返回了结果,后一个接口才能继续处理 ;这是IIS的机制,相同的 session id的时候超过一定数量的时候会出现排队现象,但是我们可以使用多用户多站点调用来提高调用效率。
【注意事项】
线程不是越多越好,应根据具体应用场景和系统资源来权衡。
【案例演示】
使用4个用户2个站点调用WebAPI接口保存客户。
【实现步骤】
<1>基于帖子https://vip.kingdee.com/article/650363039794871552?productLineId=1&isKnowledge=2&lang=zh-CN的代码做修改。
<2>代码如下。
using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.Linq; using System.Threading.Tasks; namespace Zlf.WebApiDemo { class Program { const string AppId = "296988_47aD5+sL6kH8WV8u6eSASbzLTs7aRoLL"; const string AppSecret = "566381bd78d64d83b6a2f9be05cdd01e"; const string K3cloudUrl = "http://localhost/k3cloud/";//k3cloud站点 const string K3cloudAppUrl = "http://localhost/k3cloudApp/";//k3cloudapp站点 const string DbId = "67468ad9fb6464"; static readonly ConcurrentDictionary<string, WebApiHttpInvoke> DicUser = new ConcurrentDictionary<string, WebApiHttpInvoke>(); static int _currentUserIndex = -1; static void Main(string[] args) { //本示例创建了4个用户实例,其中用了2个站点。这里采用异步的方式调用,确保4个实例是可以并行同步数据。 Console.WriteLine("保存开始.."); DicUser["demo_k3cloud"] = new WebApiHttpInvoke(K3cloudUrl, DbId, "demo", AppId,AppSecret); DicUser["demo2_k3cloudapp"] = new WebApiHttpInvoke(K3cloudUrl, DbId, "demo2", AppId,AppSecret); DicUser["demo3_k3cloud"] = new WebApiHttpInvoke(K3cloudAppUrl, DbId, "demo3", AppId,AppSecret); DicUser["demo4_k3cloudapp"] = new WebApiHttpInvoke(K3cloudAppUrl, DbId, "demo4", AppId,AppSecret); Task[] tasks = new Task[10]; for (int i = 0; i < tasks.Length; i++) { int n = i; tasks[i] = Task.Run(() => DoSave(string.Format("20241129-{0}", n))); } Task.WhenAll(tasks).Wait(); Console.WriteLine("全部保存完成.."); Console.ReadLine(); } private static void DoSave(string billNo) { var instance = GetInstance(); instance.Save("BD_Customer", billNo, CreateJson(billNo)); } /// <summary> /// 按轮询方式获取WebApiHttpInvoke实例 /// </summary> /// <returns></returns> private static WebApiHttpInvoke GetInstance() { _currentUserIndex = (_currentUserIndex + 1) % DicUser.Count; var kvp = DicUser.ElementAt(_currentUserIndex); if (kvp.Key == null || kvp.Value == null) { throw new Exception("GetInstance error"); } return kvp.Value; } private static string CreateJson(string billNo) { var data = new { IsVerifyBaseDataField = true, Model = new { FCreateOrgId = new { FNumber = "100" }, FNumber = billNo, FUseOrgId = new { FNumber = "100" }, FName = billNo, FCOUNTRY = new { FNumber = "China" }, FIsDefPayer = false, FIsGroup = false, FCustTypeId = new { FNumber = "KHLB001_SYS" }, FTRADINGCURRID = new { FNumber = "PRE001" }, FTRANSLEADTIME = 0 } }; return JsonConvert.SerializeObject(data); } } }<2>WebApiHttpInvoke.cs代码如下。
using Kingdee.BOS.WebApi.Client; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Zlf.WebApiDemo { class WebApiHttpInvoke { private readonly string _dbId, _userName, _appId, _appSecret; private readonly object _obj = new object(); private readonly K3CloudApiClient _client; private bool _isLogin; public WebApiHttpInvoke(string url, string dbId, string userName, string appId, string appSecret) { this._dbId = dbId; this._userName = userName; this._appId = appId; this._appSecret = appSecret; _client = new K3CloudApiClient(url, 10 * 60);//超时时间设为10分钟 } //保存单据 public void Save(string formId, string billNo, string data, bool isRetry = false) { string saveResult = _client.Save(formId, data); var responseStatus = JObject.Parse(saveResult)["Result"]["ResponseStatus"]; var isSuccess = responseStatus["IsSuccess"].Value<bool>(); if (!isSuccess) { var msgCode = responseStatus["MsgCode"].Value<int>(); if (msgCode == 1)//会话丢失,可能未登录或者过期了 { if (isRetry) { return; } _isLogin = false; Login(); //重新登录 Save(formId, billNo, data, true); } else { //暂存单据 Console.WriteLine("保存失败,返回结果:{0}", saveResult); } } else { Console.WriteLine("保存成功,billNo={0} ", billNo); } } /// <summary> /// 登录操作 /// </summary> /// <returns></returns> private bool Login() { lock (_obj) { if (!_isLogin) { //使用第三方系统登录授权 var loginResult = _client.LoginByAppSecret(this._dbId, this._userName, this._appId, this._appSecret, 2052); if (loginResult.Contains("response_error")) { //系统异常,包括账套id错误 throw new Exception(loginResult); } var resultType = JObject.Parse(loginResult)["LoginResultType"].Value<int>(); if (resultType == 1) { _isLogin = true; return true; } throw new Exception(loginResult); } } return true; } } }
【功能验证】
<1>运行代码。

<1>查看WebAPI日志,确认可以多用户并发保存。

上一篇:WebAPI一次登录多次调用示例 下一篇:启用webapi日志
作者:cyoukon
来源:金蝶云社区
原文链接:https://vip.kingdee.com/knowledge/650388592971234560?specialId=650386937144032256&productLineId=1&isKnowledge=2&lang=zh-CN
著作权归作者所有。未经允许禁止转载,如需转载请联系作者获得授权。