BeginInvoke与EndInvoke方法解决多线程接收委托返回值问题
大家可以先看看我上次写的文章
http://www.sufeinet.com/thread-3556-1-1.html
在这个例子中只是使用委托,在子线程中设置主线程的数据,而没有说明怎么样取返回值,
当今天有一个用户在问这个问题时我感觉应该写一下了
其实这个很简单先看下面界面
这是怎么实现的呢其实
很简单
第一步定义一个委托
//创建一个委托,是为访问TextBox控件服务的。
public
delegate
string
UpdateTxt(
string
msg);
//定义一个委托变量
public
UpdateTxt updateTxt;
|
第二步是实例化一下
private void Form1_Load_1(object sender, EventArgs e) { //实例化委托 updateTxt = new UpdateTxt(UpdateTxtMethod); }
指定的UpdateTxtMethod该当如下显示
//修改TextBox值的方法。
public
string
UpdateTxtMethod(
string
msg)
{
richTextBox1.AppendText(msg +
"\r\n"
);
return
msg;
}
|
这个主要是用来设置richTextBox1的值的。
第三步开启一个线程
//开启线程
private
void
button1_Click(
object
sender, EventArgs e)
{
Thread objThread =
new
Thread(
new
ThreadStart(
delegate
{
ThreadMethodTxt(textBox1.Text.Trim());
}));
objThread.Start();
}
|
线程主要是用来执行这个方法的ThreadMethodTxt
这个方法代码如下
//此为在非创建线程中的调用方法,其实是使用TextBox的Invoke方法。
public
void
ThreadMethodTxt(
string
n)
{
IAsyncResult ar =
this
.BeginInvoke(updateTxt, n);
//这里就是你要的返回数据
string
result =
this
.EndInvoke(ar).ToString();
this
.BeginInvoke(updateTxt,
"返回数据:"
+ result);
}
|
其实就是这两句
IAsyncResult ar = this.BeginInvoke(updateTxt, n); //这里就是你要的返回数据 string result = this.EndInvoke(ar).ToString();
这样就可以取到返回的数据了this.EndInvoke(ar)返回的是一个对象,如是其它类型大家可以使用Convert进行相应的转化就行了。
下面是全部代码大家看看吧
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Threading;
namespace
WindowsFormsApplication3
{
public
partial
class
Form1 : Form
{
public
Form1()
{
InitializeComponent();
}
//创建一个委托,是为访问TextBox控件服务的。
public
delegate
string
UpdateTxt(
string
msg);
//定义一个委托变量
public
UpdateTxt updateTxt;
//修改TextBox值的方法。
public
string
UpdateTxtMethod(
string
msg)
{
richTextBox1.AppendText(msg +
"\r\n"
);
return
msg;
}
//此为在非创建线程中的调用方法,其实是使用TextBox的Invoke方法。
public
void
ThreadMethodTxt(
string
n)
{
IAsyncResult ar =
this
.BeginInvoke(updateTxt, n);
//这里就是你要的返回数据
string
result =
this
.EndInvoke(ar).ToString();
this
.BeginInvoke(updateTxt,
"返回数据:"
+ result);
}
//开启线程
private
void
button1_Click(
object
sender, EventArgs e)
{
Thread objThread =
new
Thread(
new
ThreadStart(
delegate
{
ThreadMethodTxt(textBox1.Text.Trim());
}));
objThread.Start();
}
private
void
Form1_Load_1(
object
sender, EventArgs e)
{
//实例化委托
updateTxt =
new
UpdateTxt(UpdateTxtMethod);
}
}
}
|
欢迎大家提建议,如果那里有问题还请指教一下
<?xml version="1.0" encoding="utf-8"?> <configuration> <connectionStrings> <add name="DatabaseConnection" connectionString="Server=localhost;Port=3306;Database=yourdbname;Uid=yourusername;Pwd=yourpassword;" providerName="MySql.Data.MySqlClient" /> </connectionStrings> <!-- ... --> </configuration>
<configuration> <!-- ... --> <system.web> <!-- ... --> <authentication mode="Forms"> <forms loginUrl="~/Account/LogOn" timeout="2880" /> </authentication> <roleManager enabled="true" defaultProvider="MySQLRoleProvider"> <providers> <clear/> <add name="MySQLRoleProvider" autogenerateschema="true" type="MySql.Web.Security.MySQLRoleProvider, MySql.Web, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" connectionStringName="MarioDB" applicationName="/" /> </providers> </roleManager> <membership defaultProvider="MySQLMembershipProvider"> <providers> <clear /> <add name="MySQLMembershipProvider" autogenerateschema="true" type="MySql.Web.Security.MySQLMembershipProvider, MySql.Web, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" connectionStringName="MarioDB" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> </providers> </membership> <!-- ... ---> </system.web> </configuration>
本文出处:http://www.cnblogs.com/aces/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
请关注我的个人博客:www.afire.com.cn
最近项目中频繁遇到需要弹出窗口的功能,一直使用浏览器默认的Alert和Confirm弹窗,感觉视觉效果不是那么好,而从网上下载的话又找不到合适的,找到的话有些也是十分臃肿,有时候感觉学习配置的功夫自己也就搞一个了(顺便说一句,我呢,属于比较懒的那种人,如果学习和配置需要花很多时间的话我一般是懒得学习的)。
于是就本着“自己动手,丰衣足食”的原则,自己做了一个弹出的效果,以满足自己的“小小”的需求,可以直接通过配置CSS来修改相关样式。
主要是将Javascript中的alert和confirm这两个默认的弹窗进行了美化,在做的过程中使用了部分CSS3的一些属性,因此可能在部分低智商的比如IE系列的6、7上面会出现一些偏差,但整体上还是兼容的。
我的设计主要支持的功能如下:
1、在当前窗口的正中位置弹出窗口;
2、弹出窗口之后,有一个半透明的遮罩层将后面的内容挡着;
3、能够支持弹窗的拖动(这个功能刚好能用到前一段时间写的那个鼠标拖拽效果,可以点击这里查看,顺便将鼠标拖拽效果进行了一下更新,修订了一点点BUG);
4、部分参数的可配置;
5、可以在弹窗中引用其他的URL
6、点击确定或者取消之后可以定义要执行的函数
显示效果如下图所示:
主要代码如下所示:
先上JS
/** * DialogBySHF Library v1.0.0 * http://cnblogs.com/iamshf * * author:盛浩峰 * Date: 2013-06-14 */ (function ($) { //默认参数 var PARAMS; var DEFAULTPARAMS = { Title: "Windows弹出消息", Content: "", Width: 400, Height: 300, URL: "", ConfirmFun: new Object, CancelFun: new Object }; var ContentWidth = 0; var ContentHeight = 0; $.DialogBySHF = { //弹出提示框 Alert: function (params) { Show(params, "Alert"); }, //弹出确认框 Confirm: function (params) { Show(params, "Confirm"); }, //弹出引用其他URL框 Dialog: function (params) { Show(params, "Dialog") }, //关闭弹出框 Close: function () { $("#DialogBySHFLayer,#DialogBySHF").remove(); } }; //初始化参数 function Init(params) { if (params != undefined && params != null) { PARAMS = $.extend({},DEFAULTPARAMS, params); } ContentWidth = PARAMS.Width - 10; ContentHeight = PARAMS.Height - 45; }; //显示弹出框 function Show(params, caller) { Init(params); var screenWidth = $(window).width(); var screenHeight = $(window).height(); //在屏幕中显示的位置(正中间) var positionLeft = (screenWidth - PARAMS.Width) / 2 + $(document).scrollLeft(); var positionTop = (screenHeight - PARAMS.Height) / 2 + $(document).scrollTop(); var Content = []; Content.push("<div id=\"DialogBySHFLayer\" style=\"width:" + $(document).width() + "px;height:" + $(document).height() + "px;\"></div>"); Content.push("<div id=\"DialogBySHF\" style=\"width:" + PARAMS.Width + "px;height:" + PARAMS.Height + "px;left:" + positionLeft + "px;top:" + positionTop + "px;\">"); Content.push(" <div id=\"Title\"><span>" + PARAMS.Title + "</span><span id=\"Close\">✕</span></div>"); Content.push(" <div id=\"Container\" style=\"width:" + ContentWidth + "px;height:" + ContentHeight + "px;\">"); if (caller == "Dialog") { Content.push(" <iframe src=\"" + PARAMS.URL + "\"></iframe>"); } else { var TipLineHeight = ContentHeight - 60; Content.push(" <table>"); Content.push(" <tr><td id=\"TipLine\" style=\"height:" + TipLineHeight + "px;\">" + PARAMS.Content + "</td></tr>"); Content.push(" <tr>"); Content.push(" <td id=\"BtnLine\">"); Content.push(" <input type=\"button\" id=\"btnDialogBySHFConfirm\" value=\"确定\" />"); if (caller == "Confirm") { Content.push(" <input type=\"button\" id=\"btnDialogBySHFCancel\" value=\"取消\" />"); } Content.push(" </td>"); Content.push(" </tr>"); Content.push(" </table>"); } Content.push(" </div>"); Content.push("</div>"); $("body").append(Content.join("\n")); SetDialogEvent(caller); } //设置弹窗事件 function SetDialogEvent(caller) { $("#DialogBySHF #Close").click(function () { $.DialogBySHF.Close(); }); $("#DialogBySHF #Title").DragBySHF($("#DialogBySHF")); if (caller != "Dialog") { $("#DialogBySHF #btnDialogBySHFConfirm").click(function () { $.DialogBySHF.Close(); if ($.isFunction(PARAMS.ConfirmFun)) { PARAMS.ConfirmFun(); } }) } if (caller == "Confirm") { $("#DialogBySHF #btnDialogBySHFCancel").click(function () { $.DialogBySHF.Close(); if ($.isFunction(PARAMS.CancelFun)) { PARAMS.CancelFun(); } }) } } })(jQuery); //拖动层 (function ($) { $.fn.extend({ DragBySHF: function (objMoved) { return this.each(function () { //鼠标按下时的位置 var mouseDownPosiX; var mouseDownPosiY; //移动的对象的初始位置 var objPosiX; var objPosiY; //移动的对象 var obj = $(objMoved) == undefined ? $(this) : $(objMoved); //是否处于移动状态 var status = false; //鼠标移动时计算移动的位置 var tempX; var tempY; $(this).mousedown(function (e) { status = true; mouseDownPosiX = e.pageX; mouseDownPosiY = e.pageY; objPosiX = obj.css("left").replace("px", ""); objPosiY = obj.css("top").replace("px", ""); }).mouseup(function () { status = false; }); $("body").mousemove(function (e) { if (status) { tempX = parseInt(e.pageX) - parseInt(mouseDownPosiX) + parseInt(objPosiX); tempY = parseInt(e.pageY) - parseInt(mouseDownPosiY) + parseInt(objPosiY); obj.css({ "left": tempX + "px", "top": tempY + "px" }); } }).mouseup(function () { status = false; }).mouseleave(function () { status = false; }); }); } }) })(jQuery);
这是CSS代码,如果修改样式的话可以从此处修改
/*弹出来的遮罩层*/ #DialogBySHFLayer { position:absolute; /*width:100%; height:100%;*/ left:0; top:0; z-index:500; background-color:#333333; filter:alpha(Opacity=40); -moz-opacity:0.4; opacity: 0.4; } /*弹出的提示框*/ #DialogBySHF { position:absolute; /*left:50%; top:50%; width:400px; height:400px;*/ border-radius:10px; box-shadow:0 0 8px rgba(0, 0, 0, .8); background-color:#f2f2f2; z-index:600; } #DialogBySHF #Title { margin:0; width:100%; height:35px; background-color:#ffa500; color:#FFFFFF; font-family:微软雅黑,黑体,宋体; font-weight:bold; font-size:18px; text-align:center; cursor:move; line-height:35px; border-radius:10px 10px 0 0; } #DialogBySHF #Close { position:absolute; right:7px; top:7px; height:21px; line-height:21px; width:21px; cursor:pointer; display:block; border:1px solid #da8e02; box-shadow:0 0 4px rgba(255, 255, 255, .9); border-radius:5px; } #DialogBySHF #Container { padding:0px 5px 5px 5px; /*width:390px; height:355px;*/ } #DialogBySHF #Container table,#DialogBySHF #Container iframe { width:100%; height:100%; } #DialogBySHF #Container table td { vertical-align:middle; } #DialogBySHF #Container table #TipLine { padding:0 30px; } #DialogBySHF #Container table #BtnLine { height:60px; text-align:center; } #DialogBySHF #Container table #BtnLine input { margin:6px 11px; -moz-user-select: none; background-color:#F5F5F5; background-image: -moz-linear-gradient(center top , #F5F5F5, #F1F1F1); background-image:-ms-linear-gradient(rgb(245, 245, 245), rgb(241, 241, 241)); background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1); border:1px solid rgba(0,0,0,0.1); *border:1px solid #DDDDDD; border:1px solid #DDDDDD\0; border-radius:2px; font-family:新宋体; color:#666666; cursor:default; font-size:12px; font-weight:bold; height:29px; line-height:27px; min-width:54px; padding:0 8px; text-align:center; } #DialogBySHF #Container table #BtnLine input:hover { background-color: #F8F8F8; background-image: -moz-linear-gradient(center top , #F8F8F8, #F1F1F1); border: 1px solid #C6C6C6; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); color: #333333; } #DialogBySHF #Container table #BtnLine input:focus { border: 1px solid #4D90FE; outline: medium none; }
使用方法如下所示:
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>弹出窗体Demo演示</title> <link rel="Stylesheet" type="text/css" href="DialogBySHF.css" /> </head> <body> <input type="button" value="弹出提示框" id="btnAlert" /> <input type="button" value="弹出确认框" id="btnConfirm" /> <input type="button" value="引用其他页面" id="btnDialog" /> <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.1.min.js"></script> <script type="text/javascript" src="DialogBySHF.js"></script> <script type="text/javascript"> $(document).ready(function () { $("#btnAlert").click(function () { $.DialogBySHF.Alert({ Width: 400, Height: 300, Title: "提示信息", Content: '你好,这是弹出提示,即JS中的alert', ConfirmFun: test }); }) $("#btnConfirm").click(function () { $.DialogBySHF.Confirm({ Width: 400, Height: 300, Title: "提示信息", Content: '你好,这是确认信息,类似于JS中的confirm', ConfirmFun: test, CancelFun: testCancel }); }) $("#btnDialog").click(function () { $.DialogBySHF.Dialog({ Width: 1024, Height: 768, Title: "搜狐网站", URL: 'http://www.sohu.com' }); }) }) function test() { $.DialogBySHF.Alert({ Width: 400, Height: 300, Title: "确认后执行方法", Content: '确认后执行的方法' }); } function testCancel() { $.DialogBySHF.Alert({ Width: 400, Height: 300, Title: "取消后执行方法", Content: '取消后执行的方法' }); } </script> </body> </html>
源码和Demo都可以从这里下载:点击下载
当然,也可以在Google Code上下载源码,我将源码放在了Google Code上面,如果有更新的话也会在Google Code上面进行更新,Google Code地址为:https://code.google.com/p/dialogbyshf/