//Class WechatOfferExcutor

此类为微信触发类,属于上层调用类,其中有用到用静态变量缓存offer信息,Task异步执行发送方法等

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Velites.Utility.SharedLibrary;
using Newtonsoft.Json;
using System.Configuration;

namespace xxx.Peripheral.Wechat
{
    [ParametrType(typeof(WechatOfferParameter))]
    public class WechatOfferExcutor : MemberOfferExecutorBase<WechatOfferParameter>
    {
        static KeyValuePair<long, WechatOfferParameter> offerInfo = new KeyValuePair<long, WechatOfferParameter>();
        static WechatBatchProcess proc = new WechatBatchProcess(Send);

protected override IOfferExecutionResult ExecuteWithIDataAndMember(IData data, IMember member, WechatOfferParameter offer)
        {
            bool isValid = AssertHits(data, member, offer);
            LogStub.Log(new LogEntry("txt - AssertHits isValid", LogStub.LOG_LEVEL_ERROR));
            if (isValid && !string.IsNullOrWhiteSpace(offer.Content))
            {
                string memCode = member.GetProperty(ThreeMMemberEntitySchema.ThreeMMember.CODE).ToString();
                string toWechat = member.GetProperty(ThreeMMemberEntitySchema.ThreeMMember.WECHAT_OPENID).ToString();

List<ImgItem> itemList = new List<ImgItem>()
                {
                    new ImgItem() {
                    title = offer.Subject,
                    content = offer.Content
                    }
                };

LogEntry entry = new LogEntry(string.Format("txt - 微信发送开始, memCode = {0}, wechatOpenID = {1}, offerID = {2}", memCode, toWechat, offer.OfferID), LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(entry);

proc.AddOpenIDAndSendWechat(offer.OfferID, toWechat, itemList, offer.ExecuteTime);
                //EmailServiceApiConfigurationHub.Instance.EmailProvider.Provide().Send(wechat);

LogEntry endEntry = new LogEntry("txt - 微信发送结束", LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(endEntry);
            }
            return null;
        }

private static void Send(List<string> openIDs, List<ImgItem> imgDesc)
        {

//注意,此处必须为异步调用发送方法,否则可能导致发送超时,以至于发送失败
            Task.Run(() => WechatUtility.SendText(openIDs, imgDesc));
            offerInfo = new KeyValuePair<long, WechatOfferParameter>();
        }

public bool AssertHits(IData data, IMember member, WechatOfferParameter offer)
        {
            bool ret = true;
            if (data == null || member == null || offer == null || member.GetProperty(ThreeMMemberEntitySchema.ThreeMMember.WECHAT_OPENID) == null
                || string.IsNullOrWhiteSpace(member.GetProperty(ThreeMMemberEntitySchema.ThreeMMember.WECHAT_OPENID).ToString()))
            {
                ret = false;
                return ret;
            }
            return ret;
        }

public override WechatOfferParameter ParseToParameter(JObject jOffer, IOffer offer)
        {
            if (offerInfo.Key != offer.ID)
            {
                WechatOfferParameter wechatOffer = base.ParseToParameter(jOffer, offer);
                wechatOffer.Category = offer.CategoryKey;
                var offerParameterToken = JToken.Parse(offer.Parameter);
                if (offerParameterToken["content"] != null)
                {
                    wechatOffer.Content = offerParameterToken["content"].ToString();
                    wechatOffer.Subject = offer.Name;
                    wechatOffer.OfferID = offer.ID;

//此处给发送时间赋值
                    //如果是市场活动,没有执行时间,那么可以设置为当前时间的5分钟之后
                    //测试时可以设置为10秒
                    //wechatOffer.ExecuteTime = DateTime.Now.AddSeconds(10);
                    wechatOffer.ExecuteTime = DateTime.Now.AddMinutes(5);
                    var interval = ConfigurationManager.AppSettings["ActivityInterval"];
                    if (interval != null)
                    {
                        wechatOffer.ExecuteTime = DateTime.Now.AddMinutes(Int32.Parse(interval.ToString()));
                    }

if (jOffer != null)
                    {
                        IDictionary<string, JToken> data = JsonConvert.DeserializeObject<JObject>(jOffer.ToString());
                        var item = data.Where(p => p.Key.ToLower() == "executetime");
                        if (item != null && item.Any())
                        {
                            wechatOffer.ExecuteTime = Convert.ToDateTime(item.FirstOrDefault().Value);
                        }
                    }

offerInfo = new KeyValuePair<long, WechatOfferParameter>(offer.ID, wechatOffer);
                    return wechatOffer;
                }
            }
            return offerInfo.Value;
        }
    }
}

//Class  WechatBatchProcess

此类是发送微信的中间处理类,包括了Timer间隔触发等,并发处理Lock机制等,其他的项目可以借鉴此类。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace ThreeM.Peripheral.Wechat
{
    public class WechatBatchProcess
    {
        List<SendInfo> SendInfoList = new List<SendInfo>();
        Action<List<string>, List<ImgItem>> sendAct { set; get; }
        Timer timer;

public WechatBatchProcess(Action<List<string>, List<ImgItem>> act)
        {
            timer = new Timer();
            sendAct = act;
            //正式的可以改10分钟,测试时可以为30000即30秒
            timer.Interval = 600000;
            var interval = ConfigurationManager.AppSettings["TimerInterval"];
            if (interval != null)
            {
                timer.Interval = Int32.Parse(interval);
            }
            timer.AutoReset = false;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(Timers_Timer_Elapsed);
        }

void Timers_Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            lock (this)
            {
                var itemList = SendInfoList.Where(p => p.SendTime <= DateTime.Now).ToList();
                SendInfoList = SendInfoList.Where(p => p.SendTime > DateTime.Now).ToList();
                foreach (var item in itemList)
                {
                    Send(item);
                }

if (SendInfoList.Any())
                {
                    timer.Start();
                }
            }
        }

public void AddOpenIDAndSendWechat(long OfferID, string OpenID, List<ImgItem> ImgDesc, DateTime? SendTime)
        {
            if (!string.IsNullOrWhiteSpace(OpenID) && ImgDesc != null && ImgDesc.Any())
            {
                lock (this)
                {
                    var item = SendInfoList.FirstOrDefault(p => p.OfferID == OfferID);
                    if (item == null)
                    {
                        item = new SendInfo()
                        {
                            OfferID = OfferID,
                            OpenidList = new List<string>(),
                            ImgDesc = ImgDesc,
                        };

SendInfoList.Add(item);

}
                    item.SendTime = SendTime;
                    item.OpenidList.Add(OpenID);
                }
                timer.Start();
            }
        }

private void Send(SendInfo item)
        {
            if (item.OpenidList.Any())
            {
                sendAct(item.OpenidList, item.ImgDesc);
            }
        }
    }

public class SendInfo
    {
        public List<string> OpenidList { get; set; }
        public List<ImgItem> ImgDesc { get; set; }
        public long OfferID { get; set; }
        public DateTime? SendTime { get; set; }
    }
}

//Class  WechatUtility

此类为基础工具类,包含了发送微信时需要的HttpPost请求等方法,

包括文本请求和多张图片请求等,是一个非常有用的工具类

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Configuration;
using System.Collections.Specialized;
using Velites.Utility.SharedLibrary;

namespace xxx.Peripheral.Wechat
{
    public class WechatUtility
    {
        public static string SendText(List<string> openIDList, string content)
        {
            string url = ConfigurationManager.AppSettings["wechatImgUrl"];
            string result = string.Empty;

if (openIDList != null && openIDList.Any() && !string.IsNullOrWhiteSpace(content))
            {
                string param = string.Format("open_ids={0}&text={1}", string.Join(",",openIDList), content);
                result = HttpPostData(url, param);
            }
           
            return result;
        }

public static string SendText(List<string> openIDList, List<ImgItem> imgDesc)
        {
            string url = ConfigurationManager.AppSettings["wechatImgUrl"];
            string result = string.Empty;
            var imgInfo = imgDesc.FirstOrDefault();

if (openIDList != null && openIDList.Any() && !string.IsNullOrWhiteSpace(imgInfo.content))
            {
                //微信群发要求至少2个账号才能发送,如果只有一个时,添加一个相同的微信号
                if (openIDList.Count() == 1)
                {
                    openIDList.Add(openIDList.FirstOrDefault());
                }

string param = string.Format("open_ids={0}&text={1}", string.Join(",", openIDList), imgInfo.content);
                result = HttpPostData(url, param);
            }

return result;
        }

public static string SendImgAndText(List<string> openIDList, string title, string content, string filePath)
        {
            string url = ConfigurationManager.AppSettings["wechatImgUrl"];
            string result = string.Empty;

if (openIDList != null && openIDList.Any() && !string.IsNullOrWhiteSpace(content))
            {
                NameValueCollection col = new NameValueCollection();
                //col.Add("media", filePath);
                col.Add("title", title);
                col.Add("content", content);
                col.Add("open_ids", string.Join(",", openIDList));

result = HttpPostData(url, 60000, "media1", filePath, col);
            }

return result;
        }

public static string SendImgAndText(List<string> openIDList, List<ImgItem> imgDesc)
        {
            string url = ConfigurationManager.AppSettings["wechatImgUrl"];
            string result = string.Empty;

if (openIDList != null && openIDList.Any() && imgDesc != null)
            {
                Dictionary<string, string> imgDic = new Dictionary<string, string>();
                foreach (var item in imgDesc)
                {
                    imgDic.Add(item.name, item.path);
                }

NameValueCollection col = new NameValueCollection();
                col.Add("imgDesc", Newtonsoft.Json.JsonConvert.SerializeObject(imgDesc));
                col.Add("open_ids", string.Join(",", openIDList));
                result = HttpPostData(url, 60000, imgDic, col);
            }

return result;
        }

public static string HttpPostData(string url, string param)
        {
            LogEntry entry = new LogEntry("发送微信文本开始-HttpPostData -- " + param, LogStub.LOG_LEVEL_ERROR);
            LogStub.Log(entry);

var result = string.Empty;
            //注意提交的编码 这边是需要改变的 这边默认的是Default:系统当前编码
            byte[] postData = Encoding.UTF8.GetBytes(param);

// 设置提交的相关参数
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            Encoding myEncoding = Encoding.UTF8;
            request.Method = "POST";
            request.KeepAlive = false;
            request.AllowAutoRedirect = true;
            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR  3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
            request.ContentLength = postData.Length;

// 提交请求数据
            System.IO.Stream outputStream = request.GetRequestStream();
            outputStream.Write(postData, 0, postData.Length);
            outputStream.Close();

HttpWebResponse response;
            Stream responseStream;
            StreamReader reader;
            string srcString;
            response = request.GetResponse() as HttpWebResponse;
            responseStream = response.GetResponseStream();
            reader = new System.IO.StreamReader(responseStream, Encoding.GetEncoding("UTF-8"));
            srcString = reader.ReadToEnd();
            result = srcString;   //返回值赋值
            reader.Close();

entry = new LogEntry("发送微信文本结束-HttpPostData -- " + result, LogStub.LOG_LEVEL_ERROR);
            LogStub.Log(entry);
            return result;
        }

private static string HttpPostData(string url, int timeOut, string fileKeyName,
                                    string filePath, NameValueCollection stringDict)
        {
            string fileKeyName2 = "media2";
            string filePath2 = @"C:\Users\gaoj007\Pictures\1aliuh.jpg";

string responseContent;
            var memStream = new MemoryStream();
            var webRequest = (HttpWebRequest)WebRequest.Create(url);
            // 边界符
            var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
            // 边界符
            var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
            var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            // 最后的结束符
            var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n");

// 设置属性
            webRequest.Method = "POST";
            webRequest.Timeout = timeOut;
            webRequest.ContentType = "multipart/form-data; boundary=" + boundary;

// 写入文件
            const string filePartHeader =
                "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
                 "Content-Type: application/octet-stream\r\n\r\n";
            var header = string.Format(filePartHeader, fileKeyName, filePath);
            var headerbytes = Encoding.UTF8.GetBytes(header);

memStream.Write(beginBoundary, 0, beginBoundary.Length);
            memStream.Write(headerbytes, 0, headerbytes.Length);

var buffer = new byte[1024];
            int bytesRead; // =0

while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                memStream.Write(buffer, 0, bytesRead);
            }

//第二章图片
            //memStream.Write(beginBoundary, 0, beginBoundary.Length);

//var aaa = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
            //memStream.Write(aaa, 0, aaa.Length);

string nxetFileFormat = "\r\n--" + boundary + "\r\n" + filePartHeader;

header = string.Format(nxetFileFormat, fileKeyName2, filePath2);
            headerbytes = Encoding.UTF8.GetBytes(header);

memStream.Write(headerbytes, 0, headerbytes.Length);
            fileStream = new FileStream(filePath2, FileMode.Open, FileAccess.Read);
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                memStream.Write(buffer, 0, bytesRead);
            }

// 写入字符串的Key
            var stringKeyHeader = "\r\n--" + boundary +
                                   "\r\nContent-Disposition: form-data; name=\"{0}\"" +
                                   "\r\n\r\n{1}\r\n";

foreach (byte[] formitembytes in from string key in stringDict.Keys
                                             select string.Format(stringKeyHeader, key, stringDict[key])
                                                 into formitem
                                                 select Encoding.UTF8.GetBytes(formitem))
            {
                memStream.Write(formitembytes, 0, formitembytes.Length);
            }

// 写入最后的结束边界符
            memStream.Write(endBoundary, 0, endBoundary.Length);

webRequest.ContentLength = memStream.Length;

var requestStream = webRequest.GetRequestStream();

memStream.Position = 0;
            var tempBuffer = new byte[memStream.Length];
            memStream.Read(tempBuffer, 0, tempBuffer.Length);
            memStream.Close();

requestStream.Write(tempBuffer, 0, tempBuffer.Length);
            requestStream.Close();

var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();

using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
                                                            Encoding.GetEncoding("utf-8")))
            {
                responseContent = httpStreamReader.ReadToEnd();
            }

fileStream.Close();
            httpWebResponse.Close();
            webRequest.Abort();

return responseContent;
        }

private static string HttpPostData(string url, int timeOut, Dictionary<string, string> imgDic, NameValueCollection stringDict)
        {
            LogEntry entry = new LogEntry("发送微信图片开始-HttpPostData open_ids-- " + stringDict["open_ids"], LogStub.LOG_LEVEL_ERROR);
            LogStub.Log(entry);
            try
            {
                entry = new LogEntry("发送微信图片开始-HttpPostData imgDic-- " + string.Join(",", imgDic), LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(entry);

entry = new LogEntry("发送微信图片开始-HttpPostData imgDic-- first--" + imgDic.FirstOrDefault().Key + " -- " +
                imgDic.FirstOrDefault().Value + "--last--" + imgDic.LastOrDefault().Key + " -- " + imgDic.LastOrDefault().Value + "--count--" + imgDic.Count(), LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(entry);

var firstImg = imgDic.FirstOrDefault();
                string fileKeyName = firstImg.Key;
                string filePath = firstImg.Value;

string responseContent;
                var memStream = new MemoryStream();
                var webRequest = (HttpWebRequest)WebRequest.Create(url);
                // 边界符
                var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
                // 边界符
                var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
                //var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);

// 最后的结束符
                var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n");

// 设置属性
                webRequest.Method = "POST";
                webRequest.Timeout = timeOut;
                webRequest.ContentType = "multipart/form-data; boundary=" + boundary;

// 写入文件
                const string filePartHeader =
                    "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
                     "Content-Type: application/octet-stream\r\n\r\n";
                var header = string.Format(filePartHeader, fileKeyName, filePath);
                var headerbytes = Encoding.UTF8.GetBytes(header);

memStream.Write(beginBoundary, 0, beginBoundary.Length);
                memStream.Write(headerbytes, 0, headerbytes.Length);

//var buffer = new byte[1024];
                //int bytesRead; // =0

//while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                //{
                //    memStream.Write(buffer, 0, bytesRead);
                //}

WebClient wc = new WebClient();
                byte[] buffer = wc.DownloadData(filePath);
                memStream.Write(buffer, 0, buffer.Length);

string imgName = string.Empty;
                string imgPath = string.Empty;
                foreach (var img in imgDic.Where(p => p.Key != fileKeyName))
                {
                    imgName = img.Key;
                    imgPath = img.Value;

string nxetFileFormat = "\r\n--" + boundary + "\r\n" + filePartHeader;

header = string.Format(nxetFileFormat, imgName, imgPath);
                    headerbytes = Encoding.UTF8.GetBytes(header);

memStream.Write(headerbytes, 0, headerbytes.Length);
                    //fileStream = new FileStream(imgPath, FileMode.Open, FileAccess.Read);
                    //while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    //{
                    //    memStream.Write(buffer, 0, bytesRead);
                    //}

buffer = wc.DownloadData(imgPath);
                    memStream.Write(buffer, 0, buffer.Length);
                }

// 写入字符串的Key
                var stringKeyHeader = "\r\n--" + boundary +
                                       "\r\nContent-Disposition: form-data; name=\"{0}\"" +
                                       "\r\n\r\n{1}\r\n";

foreach (byte[] formitembytes in from string key in stringDict.Keys
                                                 select string.Format(stringKeyHeader, key, stringDict[key])
                                                     into formitem
                                                     select Encoding.UTF8.GetBytes(formitem))
                {
                    memStream.Write(formitembytes, 0, formitembytes.Length);
                }
                // 写入最后的结束边界符
                memStream.Write(endBoundary, 0, endBoundary.Length);

webRequest.ContentLength = memStream.Length;
                var requestStream = webRequest.GetRequestStream();
                memStream.Position = 0;
                var tempBuffer = new byte[memStream.Length];
                memStream.Read(tempBuffer, 0, tempBuffer.Length);
                memStream.Close();
                requestStream.Write(tempBuffer, 0, tempBuffer.Length);
                requestStream.Close();

var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
                using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
                                                                Encoding.GetEncoding("utf-8")))
                {
                    responseContent = httpStreamReader.ReadToEnd();
                }
                //fileStream.Close();
                httpWebResponse.Close();
                webRequest.Abort();

entry = new LogEntry("发送微信图片结束-HttpPostData -- " + responseContent, LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(entry);

return responseContent;
            }
            catch (Exception er)
            {
                entry = new LogEntry("发送微信图文发生异常 -- HttpPostData -- " + er.ToString(), LogStub.LOG_LEVEL_ERROR);
                LogStub.Log(entry);
            }

return null;
        }

}
}

利用缓存、Timer间隔时间发送微信的实例,很有用的例子的更多相关文章

  1. 小笔记:Timer定时间隔时间操作

    小笔记:Timer定时间隔时间操作,后面有时间再补充和完善: public class TimingSvc { /// <summary> /// 定时器,执行定时任务 /// </ ...

  2. Python3.x:简单时间调度Timer(间隔时间执行)

    Python3.x:简单时间调度Timer(间隔时间执行) threading模块中的Timer能够帮助实现定时任务,而且是非阻塞的: 代码: import threading import time ...

  3. python使用itchat发送微信消息提醒

    最近在学习一点python,先找了找有趣的应用,实际修改跑了一下提高兴趣程度. 找到itchat,它的简介是这样的: “itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单. ...

  4. 使AJAX调用尽可能利用缓存特性

    优化网站设计(十四):使AJAX调用尽可能利用缓存特性 前言 网站设计的优化是一个很大的话题,有一些通用的原则,也有针对不同开发平台的一些建议.这方面的研究一直没有停止过,我在不同的场合也分享过这样的 ...

  5. Java:利用java Timer类实现定时执行任务的功能

    一.概述 在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类.其中Timer是用来在一个后台线程按指定的计划来执行指定的任务.TimerTask一个抽象类,它的子类代 ...

  6. 利用fiddler和mock调试本地微信网页

    利用fiddler和mock调试本地微信网页 微信公众号网页是比较特殊的页面,普通页面直接打开即可访问,但对于需要请求微信相关接口的部分需要安全域名认证.这导致了使用mock数据进行开发的页面没办法走 ...

  7. c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度

    linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...

  8. Java定时任务:利用java Timer类实现定时执行任务的功能

    一.概述 在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类.其中Timer是用来在一个后台线程按指定的计划来执行指定的任务. TimerTask一个抽象类,它的子类 ...

  9. [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能

    [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种. ...

随机推荐

  1. C# WinForm多线程(三)Control.Invoke

    下面我们就把在Windows Form软件中使用Invoke时的多线程要注意的问题给大家做一个介绍. 首先,什么样的操作需要考虑使用多线程?总的一条就是,负责与用户交互的线程(以下简称为UI线程)应该 ...

  2. Tian Ji -- The Horse Racin

    Tian Ji -- The Horse Racin Problem Description Here is a famous story in Chinese history. "That ...

  3. Spark 1.0.0版本发布

    前言 如今Spark终于迈出了里程碑一步,1.0.0标记的版本号出版物Spark1.0时代.1.0.0版本号不仅增加了非常多新特性.而且提供了更好的API支持.Spark SQL作为一个新的组件增加. ...

  4. 流量计算-Jstorm提交Topology过程(下一个)

    马上部分流量计算-Jstorm提交Topology过程(上), 5.上篇任务已经ServiceHandler.submitTopologyWithOpts()方法.在该方法中,会实例化一个Topolo ...

  5. Git使用汇总

    1.下载代码,代码被下载到本地 git clone https://github.com/nuptboyzhb 2.提交代码 git commit -a -m "期间提交的信息叙述性说明&q ...

  6. 开源Math.NET基础数学类库使用(06)数值分析之线性方程组直接求解

    原文:[原创]开源Math.NET基础数学类库使用(06)数值分析之线性方程组直接求解 开源Math.NET基础数学类库使用系列文章总目录:   1.开源.NET基础数学计算组件Math.NET(一) ...

  7. Visual Studio 使用及调试必知必会

    原文:Visual Studio 使用及调试必知必会   一:C# CODING 技巧 1:TODO 然后 CTRL + W + T,打开任务列表,选中 Comments,就会显示所有待做的任务 2: ...

  8. Oracle中REGEXP_SUBSTR及其它支持正则表达式的内置函数小结

    Oracle中REGEXP_SUBSTR函数的使用说明: 题目如下:在oracle中,使用一条语句实现将'17,20,23'拆分成'17','20','23'的集合. REGEXP_SUBSTR函数格 ...

  9. android:ViewPager动画摘要

    动画节目: 我们可以用ViewPager的setPageTransformer办法,至ViewPager动画.示及效果: 1.CubeInTransformer 2.CubeOutTransforme ...

  10. 命令模式 & 策略模式 & 模板方法

    一.策略模式 策略模式:封装易变化的算法,可互相替换. GoF<设计模式>中说道:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换.该模式使得算法可独立于它们的客户变化. 比如 ...