C#异步编程

 首先申明目标框架是.net framework4.7.2

这是调用paypal接口支付的开发的一次经历

var t1= CreateOrderSample.CreateOrder(body.order_id);
            t1.Wait();//卡死
            var aa = t1.Result;
            var createOrderResult = aa.Result<Order>();
//@@@@@@@@@@@@@@@@@@@@@@@@@
 var t1 = CreateOrderSample.CreateOrder(body.order_id).ConfigureAwait(false);
            var aa = t1.GetAwaiter().GetResult(); //卡死          
            var createOrderResult = aa.Result<Order>();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@
var t1 = CreateOrderSample.CreateOrder(body.order_id);
            var aa = t1.GetAwaiter().GetResult();  //卡死         
            var createOrderResult = aa.Result<Order>();
看这篇博客https://www.cnblogs.com/xiaoxiaotank/p/13529413.html 的8/5,
用了getawaiter().getresult()之后不需要用configureawait


Task<PayPalHttp.HttpResponse> t1 = Task.Run(() => CreateOrderSample.CreateOrder(body.order_id));
            t1.Wait();
            var aa = t1.Result;
            var createOrderResult = aa.Result<Order>();

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Task<PayPalHttp.HttpResponse> t1 = Task.Run(() => CreateOrderSample.CreateOrder(body.order_id));
            //t1.Wait();
            var aa = t1.Result;
            var createOrderResult = aa.Result<Order>();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Task<PayPalHttp.HttpResponse> t1 = Task.Run(async() => await CreateOrderSample.CreateOrder(body.order_id));
            //t1.Wait();
            var aa = t1.Result;
            var createOrderResult = aa.Result<Order>();
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
var taskCompletionSource = new TaskCompletionSource<PayPalHttp.HttpResponse>();
            var task1 = taskCompletionSource.Task;
            Task.Run(() =>
           {
               var result =
               taskCompletionSource.SetResult(result);
           });
            var task1Result = task1.Result;
            var captureOrderResult = task1Result.Result<Order>();


public async static Task<PayPalHttp.HttpResponse>  CreateOrder(string orderid)
        {
            var request = new OrdersCreateRequest();
            request.Headers.Add("prefer", "return=representation");
            request.RequestBody(BuildRequestBody(orderid));

            var response = await PayPalClient.client().Execute(request);
            
            return response;
        }

这是我把项目里发送邮件的方法改成异步线程执行

在编码的时候我们可以设置Thread类的IsBackground的属性来确定该线程是前台线程还是后台线程。

当在主线程中创建了一个线程,那么该线程的IsBackground默认是设置为FALSE的。

当主线程退出的时候,IsBackground=FALSE的线程还会继续执行下去,直到线程执行结束。

IsBackground=TRUE的线程才会随着主线程的退出而退出。

原理:只要所有前台线程都终止后,CLR就会对每一个活在的后台线程调用Abort()来彻底终止应用程序。

/// <summary>
        /// 发邮件
        /// </summary>
        public static void sendEmail(object a)
        {
            List<string> list = a as List<string>;
            string exhiid = list[0];
            string dz = list[1];
            string bt = list[2];
            string nr = list[3];
            connection con = new connection();
            string jg = "";

            dz = yzin.getStr(dz);
            bt = yzin.getStr(bt);
            nr = yzin.getStr(nr);
            if (dz != "" && bt != "" && nr != "")
            {
                DataTable dt1 = new DataTable();
                dt1 = con.ExeSql("select mail_dz,mail_mc,mail_user,mail_pass,mail_smtp from mail_inf where id=1 and del=0");
                if (dt1.Rows.Count > 0)
                {
                    string sdz = dt1.Rows[0]["mail_smtp"].ToString();
                    jmail.Message jmessage = new jmail.Message();
                    jmessage.Charset = "GB2312";//编码
                    jmessage.From = dt1.Rows[0]["mail_dz"].ToString();//发送人的邮件地址
                    jmessage.FromName = dt1.Rows[0]["mail_mc"].ToString();//发送人的姓名
                                                                          //jmessage.ReplyTo="dafen@ynable.com";//回复时的地址
                    jmessage.ContentType = "text/html";
                    jmessage.MailServerUserName = dt1.Rows[0]["mail_user"].ToString();//发送人邮箱的用户名
                    jmessage.MailServerPassWord = dt1.Rows[0]["mail_pass"].ToString();//发送人邮箱的密码
                    jmessage.Subject = bt;//邮件主题
                    jmessage.AddRecipient(dz, "", "");//接收人的邮件地址,姓名
                    jmessage.Body = nr;//邮件内容

                    try
                    {
                        jmessage.Send(sdz,false);//发送人邮箱的smtp服务器地址

                        jg = "OK";
                        con.ExeSql("insert into sms_records (exhiid,lx,number,nr,jg,sj) values ('" + exhiid + "','email','" + dz + "','" + nr + "','" + jg + "','" + DateTime.Now.ToString() + "')");
                    }
                    catch (Exception ex)
                    {
                        jg = ex.Message;
                        con.ExeSql("insert into sms_records (exhiid,lx,number,nr,jg,sj) values ('" + exhiid + "','email','" + dz + "','" + nr + "','" + jg + "','" + DateTime.Now.ToString() + "')");
                        jmessage.Close();
                    }

                    jmessage.Close();
                }
                dt1.Clear();
            }
            //return jg;
        }


public static void sendAsync(string exhiid, string dz, string bt, string nr)
        {
            List<string> list = new List<string>() {exhiid,dz,bt,nr };
            Thread t = new Thread(new ParameterizedThreadStart(sendEmail));
            t.IsBackground = false;
            t.Start(list);
        }

这样写也可以

 public static void sendAsync(string exhiid, string dz, string bt, string nr)
        {
            List<string> list = new List<string>() {exhiid,dz,bt,nr };
            Thread t = new Thread(()=>sendEmail(exhiid, dz, bt, nr));//new 一个带参的线程
            t.IsBackground = true;//设置为后台线程
            t.Start();//给线程传入参数
        }
jmessage.Send(sdz,false);//发送人邮箱的smtp服务器地址

这样写就不行

Thread t = new Thread(() => jmessage.Send(sdz, false));//new 一个带参的线程
                        t.Start();

爆出这个错误是因为主线程在子线程发送邮件之前把jmessage.Close(); 所以抛出了这个异常

如果把下面的jmessage.Close();删除就正常了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值