㈠ 如何写一个“异步函数”
我们平常编程写的函数 几乎都是同步调用函数,那么我们如何写一个异步执行的函数呢?!我想这个问题也许是哪些比较喜欢专研的程序员或者具有专研精神的人士回提出的问题吧!我们很多人已经习惯了windows系统提供的一些异步机制,使用这些异步机制我们很快的就能实现一些异步操作甚至可以很容易的实现一个异步执行的函数;但是我们研究过实现一个“异步函数”的本质吗?! 在单线程的系统中,所以的指令执行都是顺序执行的,这就暗示了如果一个函数A中调用了函数B,则A必须等到B执行后才能继续执行A中剩下的代码。 在多线程中,如果我们有一个threadA线程,在该线程中调用了一个函数C,而该C函数我们想将它实现成异步执行的,而异步执行必须要有多线程支持;如果我们在Windows中编写程序,创建一个线程是很简单只要使用 HANDLE WINAPI CreateThread( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in_opt LPVOID lpParameter, __in DWORD dwCreationFlags, __out_opt LPDWORD lpThreadId); 函数就可以创建一个线程。 那么我们按如下方式可以实现一个异步的FuncC函数: (1)先把你要异步完成的工作单独写成要给函数,如 DWORD WINAPI AsyncronousThread( LPVOID lpParameter // thread data){ .....}(2)在函数FuncC中使用CreateThtread函数将(1)中的函数创建一成一个线程,然后直接返回。 CreateThread(....,AsyncronousThread,...);return;}当然,写一个异步函数的方法很多,但是一个本质不会变,就是必须要依据多线程才能实现。
㈡ C # 异步怎么实现
解释名词可能比较枯燥,我还是拿一个异步登录的例子来给你吧:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace SysUI
{
public partial class UserLogin : Form
{
public bool IsLogin;
private string useName = string.Empty;
private string usePassword = string.Empty;public UserLogin()
{
InitializeComponent();
}private int loginstate = -1;
/// <summary>
/// 创建异步调用委托
/// </summary>
/// <returns></returns>
private delegate int AsyncMethodCaller();/// <summary>
/// 取消登录
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
IsLogin = false;
this.Close();
}/// <summary>
/// 验证并返回登录状态[异步方法]
/// </summary>
/// <returns></returns>
private int ToLogin()
{
try
{
DignityVerifiesServer.DignityVerifiesServer LogInObj = new SysUI.DignityVerifiesServer.DignityVerifiesServer();
int loginstate = LogInObj.DignityVerifies(this.useName, this.usePassword);
LogInObj.Dispose();
return loginstate;
}
catch
{
return 403;
}
}/// <summary>
/// 异步回调函数
/// </summary>
/// <param name="ar"></param>
private void Callback(IAsyncResult ar)
{
AsyncMethodCaller caller = (AsyncMethodCaller)ar.AsyncState;
loginstate = (int)caller.EndInvoke(ar);
MethodInvoker UnLoading = new MethodInvoker(this.Unlogin);
UserService.UserService UseId = new SysUI.UserService.UserService();
int userId = -1;
Service.Service WriteLog = new SysUI.Service.Service();
switch (loginstate)
{
case 404:
MessageBox.Show("登录失败:\r\r返回状态码:" + loginstate.ToString() + "\r\r错误描述:指定的用户不存在!", "登录失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 403:
MessageBox.Show("登录失败:\r\r返回状态码:" + loginstate.ToString() + "\r\r错误描述:无法连接到服务器!", "登录失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 400:
userId = UseId.getSelectedUserId(this.useName);
WriteLog.WriteLog("登录失败:原因,此用户已在使用中。", userId);
MessageBox.Show("用户不可用:\r\r返回状态码:" + loginstate.ToString() + "\r\r错误描述:指定的用户已经登录,无法继续使用此用户!", "登录失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 500:
userId = UseId.getSelectedUserId(this.useName);
WriteLog.WriteLog("登录失败:原因,密码错误。", userId);
MessageBox.Show("登录失败:\r\r返回状态码:" + loginstate.ToString() + "\r\r错误描述:密码错误!", "登录失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case 100:
userId = UseId.getSelectedUserId(this.useName);
UseId.ReplacementOnLineState(userId, 1);
IsLogin = true;
WriteLog.WriteLog("登录成功。", userId);
break;
default:
MessageBox.Show("登录失败:\r\r返回非遇期的状态码:" + loginstate.ToString() + "\r\r错误描述:内部应用程序异常!", "应用程序错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
}
UseId.Dispose();
WriteLog.Dispose();
this.Invoke(UnLoading);
}/// <summary>
/// 登录事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
this.StartLogIn();
}/// <summary>
/// 执行登录
/// </summary>
private void StartLogIn()
{
if (textBox1.Text == null || textBox1.Text.Trim() == "")
{
MessageBox.Show("请输入用户名!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
this.Unlogin();
textBox1.Focus();
return;
}
if (textBox2.Text == null || textBox2.Text.Trim() == "")
{
MessageBox.Show("请输入登录密码!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
this.Unlogin();
textBox2.Focus();
return;
}
this.useName = textBox1.Text.Trim();
this.usePassword = textBox2.Text.Trim();
this.logining();
/******************创建异步委托实例*****************/
AsyncMethodCaller caller = new AsyncMethodCaller(this.ToLogin);
IAsyncResult result = caller.BeginInvoke(new AsyncCallback(this.Callback), caller);
//IAsyncResult result = caller.BeginInvoke(textBox1.Text.Trim(), textBox2.Text.Trim(), null, null);
this.logining();
}
/// <summary>
/// 启动登录提示
/// </summary>
private void logining()
{
label1.Visible = false;
label2.Visible = false;
textBox1.Visible = false;
textBox2.Visible = false;
button1.Visible = false;
button2.Visible = false;
btnConfig.Visible = false;
label3.Visible = true;
LoadingImg.Visible = true;
}/// <summary>
/// 关闭登录提示
/// </summary>
private void Unlogin()
{
label3.Visible = false;
LoadingImg.Visible = false;
label1.Visible = true;
label2.Visible = true;
textBox1.Visible = true;
textBox2.Visible = true;
button1.Visible = true;
button2.Visible = true;
btnConfig.Visible = true;
if (loginstate == 100)
this.Close();
}private void button1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
e.Handled = true;
this.StartLogIn();
}
}private void UserLogin_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
e.Handled = true;
SendKeys.Send("{TAB}");
}
}/// <summary>
/// 配置按钮触发事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnConfig_Click(object sender, EventArgs e)
{
ConfigEdit frm = new ConfigEdit();
frm.ShowDialog();
}
}
}
㈢ 如何使用backgroundWorker进行异步操作
组件介绍
BackgroundWorker类位于System.ComponentModel 命名空间中,通过该类在单独的线程上执行操作实现基于事件的异步模式。下面对BackgroundWorker类的主要成员进行介绍。
BackgroundWorker类的第1个主要方法是RunWorkerAsync,该方法提交一个以异步方式启动运行操作的请求,发出请求后,将引发 DoWork 事件,在事件处理程序中开始执行异步操作代码。RunWorkerAsync 方法签名如下,
publicvoidRunWorkerAsync();
publicvoidRunWorkerAsync(Object argument);
如果异步操作需要操作参数,可以将其作为argument参数提供,由于参数类型为Object,因此访问时可能需要进行类型转换。
CancelAsync 方
法提交终止异步操作的请求,并将 CancellationPending 属性设置为 true。需要注意的是,CancelAsync
方法是否调用成功,同WorkerSupportsCancellation
属性相关,如果允许取消执行的异步操作,需将WorkerSupportsCancellation
属性设置为true,否则调用该方法将抛出异常。CancelAsync方法不含参数,方法签名如下,
publicvoid CancelAsync();
调用 CancelAsync
方法时,BackgroundWorker的 CancellationPending
属性值将被设置为true,因此在编写单独线程中执行的辅助方法时,代码中应定期检查 CancellationPending
属性,查看是否已将该属性设置为 true,如果为true,应该结束辅助方法的执行。有一点需要注意的是,DoWork
事件处理程序中的代码有可能在发出取消请求时已经完成处理工作,因此,DoWork事件处理程序或辅助方法可能会错过设置
CancellationPending属性为true的时机。在这种情况下,即使调用
CancelAsync方法发出了取消异步操作请求,RunWorkerCompleted
事件处理程序中RunWorkerCompletedEventArgs 参数的 Cancelled 标志也不会被设置为
true,这是在多线程编程中经常会出现的竞争条件问题,因此编写代码的时候需要考虑。
在执行异步操作时,如果需要跟踪异步操作执行进度,BackgroundWorker类提供了 ReportProgress 方法,调用该方法将引发 ProgressChanged 事件,通过注册该事件在事件处理程序中获取异步执行进度信息。方法签名如下:
publicvoidReportProgress(int percentProgress);
publicvoidReportProgress(int percentProgress,Object userState);
该方法包含两个版本,percentProgress表示进度百分比,取值为0-100,userState为可选参数表示自定义用户状态。
同CancelAsync 方法一样,BackgroundWorker的WorkerReportsProgress 属性设置为 true时,ReportProgress 方法才会调用成功,否则将引发InvalidOperationException异常。
上面已经提到了
BackgroundWorker的3个属性,CancellationPending用来提示操作是否已经取
消,WorkerReportsProgress和WorkerSupportsCancellation分别用来设置是否允许进度汇报和进行取消操作。
publicboolCancellationPending { get; }
{ get; set; }
{ get; set; }
另外一个会用到的属性是IsBusy,
publicbool IsBusy { get; }
通过该属性查询BackgroundWorker实例是否正在运行异步操作,如果 BackgroundWorker 正在运行异步操作,则为true,否则为false。
BackgroundWorker类包含3个事件,在事件处理程序中可进行异步操作辅助代码编写和同用户界面信息交互。
publiceventDoWorkEventHandler DoWork;
ProgressChanged;
RunWorkerCompleted;
DoWork事
件处理程序用来调用辅助方法进行实际处理操作,由于该事件处理程序在不同于UI的线程上执行,因此需要确保在 DoWork
事件处理程序中不操作任何用户界面对象。如果辅助方法需要参数支持,可以通过RunWorkerAsync方法传入,在 DoWork
事件处理程序中,通过 DoWorkEventArgs.Argument 属性提取该参数。在异步操作期间,可以通过
ProgressChanged事件处理程序获取异步操作进度信息,通过RunWorkerCompleted
事件处理程序获取异步操作结果信息,在ProgressChanged和RunWorkerCompleted的事件处理程序中可以安全的同用户界面进行
通信。
应用示例
下面通过一个简单的示例来演示BackgroundWorker组件的典型应用。在本示例中,实现一个数值的求和操作,该操作本身运行很快,为模拟处理过程有一个可感知的时间段,在辅助方法中调用了Thread.Sleep方法。
示例程序通过Windows Forms展示,显示了对1-100的数值进行求和操作,界面如下,
图1:应用程序界面
下面对主要实现代码进行说明,先看一下BackgroundWorker类的初始化,在初始化过程中注册了3个事件,允许异步辅助方法调用,以及异步操作进度通知和操作取消。
private System.ComponentModel.BackgroundWorker backgroundWorker1;
private void InitializeBackgoundWorker()
{
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
this.backgroundWorker1.WorkerReportsProgress = true;
this.backgroundWorker1.WorkerSupportsCancellation = true;
this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
this.backgroundWorker1.RunWorkerCompleted += new (backgroundWorker1_RunWorkerCompleted);
}
通过StartAsync按钮事件处理程序开始异步处理操作请求,事件处理程序如下,
private void startAsyncButton_Click(object sender, EventArgs e)
{
resultLabel.Text = String.Empty;
this.numericUpDown1.Enabled = false;
this.startAsyncButton.Enabled = false;
this.cancelAsyncButton.Enabled = true;
//获取计算数值.
int numberToCompute = (int)numericUpDown1.Value;
//启动异步操作.
backgroundWorker1.RunWorkerAsync(numberToCompute);
}
startAsyncButton_Click处理程序首先对一些界面控件进行状态设置,然后调用BackgroundWorker实例的RunWorkerAsync方法开始执行异步操作,而此时就会触发DoWork事件。
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
e.Result = ComputeAdd((int)e.Argument, worker, e);
}
在DoWork事件处理程序中,通过DoWorkEventArgs.Argument属
性获取传入的参数传递给ComputeAdd辅助方法,并把处理结果保存到DoWorkEventArgs.Result属性中,最后在
RunWorkerCompleted 事件处理程序的RunWorkerCompletedEventArgs.Result
属性中获取处理结果。如果在DoWork事件处理程序中出现异常,则 BackgroundWorker 将捕获该异常并将其传递到
RunWorkerCompleted 事件处理程序,在该事件处理程序中,异常信息作为 RunWorkerCompletedEventArgs 的
Error 属性公开。
private long ComputeAdd(int n, BackgroundWorker worker, DoWorkEventArgs e)
{
long result = 0;
for (int i = 1; i <= n; i++)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
result += i;
Thread.Sleep(500);
int percentComplete = (int)((float)i / (float)n * 100);
worker.ReportProgress(percentComplete);
}
}
return result;
}
在辅助方法中,代码定期访问BackgroundWorker实
例的CancellationPending属性,如果调用了BackgroundWorker的CancelAsync
方法,那么CancellationPending属性值就会被设置为true,辅助方法就结束执行。另外,在辅助方法中实现了进度汇报功能,通过调用
worker.ReportProgress方法触发ProgressChanged事件,接着通过ProgressChanged事件处理程序来更新进
度显示。
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
最后,在
RunWorkerCompleted事件处理程序中可以得到异步处理结果信息,分析异步操作是正常执行结束还是在处理中被取消或者是执行出现错误异常而
终止。对于处理结果信息的访问有一个标准的顺序,先是判断异步处理是否异常结束,接着判断是否执行了取消操作,最后访问处理结果。
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
resultLabel.Text = "Canceled";
}
else
{
resultLabel.Text = e.Result.ToString();
}
this.numericUpDown1.Enabled = true;
startAsyncButton.Enabled = true;
cancelAsyncButton.Enabled = false;
}
㈣ 程序开发中异步生成器函数的用法
异步生成器函数就是使用def定义的函数yield
在一个使用 async def 定义的函数或方法中出现的 yield 表达式会进一步将该函数定义为一个 asynchronous generator 函数。
当一个异步生成器函数被调用时,它会返回一个名为异步生成器对象的异步迭代器。 此对象将在之后控制该生成器函数的执行。 异步生成器对象通常被用在协程函数的 async for 语句中,类似于在 for 语句中使用生成器对象。
调用异步生成器的方法之一将返回 awaitable 对象,执行会在此对象被等待时启动。 到那时,执行将前往第一个 yield 表达式,在那里它会再次暂停,将 expression_list 的值返回给等待中的协程。 与生成器一样,挂起意味着局部的所有状态会被保留,包括局部变量的当前绑定、指令的指针、内部求值的堆栈以及任何异常处理的状态。 当执行在等待异步生成器的方法返回下一个对象后恢复时,该函数可以从原状态继续进行,就仿佛 yield 表达式只是另一个外部调用。 恢复执行之后 yield 表达式的值取决于恢复执行所用的方法。 如果使用 __anext__() 则结果为 None。 否则的话,如果使用 asend() 则结果将是传递给该方法的值。
在异步生成器函数中,yield 表达式允许出现在 try 结构的任何位置。 但是,如果一个异步生成器在其被终结(由于引用计数达到零或被作为垃圾回收)之前未被恢复,则then a yield expression within a try 结构中的 yield 表达式可能导致挂起的 finally 子句执行失败。 在此情况下,应由运行该异步生成器的事件循环或任务调度器来负责调用异步生成器-迭代器的 aclose() 方法并运行所返回的协程对象,从而允许任何挂起的 finally 子句得以执行。
为了能处理最终化,事件循环应该定义一个 终结器 函数,它接受一个异步生成器-迭代器且可能调用 aclose() 并执行协程。 这个 终结器 可能通过调用 sys.set_asyncgen_hooks() 来注册。 当首次迭代时,异步生成器-迭代器将保存已注册的 终结器 以便在最终化时调用。
㈤ 请问linux下C编程多线程同步和异步的区别,如何能实现程序的同步和异步编程
同步就是使得两个或者多个进程之间的行为按照一定的时序来执行。比如说线程A完成了某件事,然后线程B才能做某件事。具体一点,就是,线程间的某个动作执行前需要确认一个或者多个其他线程的当前状态。而异步则是多个线程各跑各的,互不干涉。
Linux下的多线程实现由pthread库提供,头文件为pthread.h。多线程最重要的就是要保护好共享资源(用互斥体,mutex),尤其是异步。代码哥哥就不上了,这里关键的不是代码的问题,也不是Linux、Windows的问题,重要的是概念的理解。哥们不妨先研究研究“生产者-消费者”这个常出现在教科书上的模型,这是一个典型的同步问题。就讲这么多了,拜拜。
㈥ VB如何实现异步执行有哪几种方法
在标准模块中写入以下代码:
Public Const SYNCHRONIZE = &H100000
Public Const INFINITE = &HFFFFFFFF
Public Const WAIT_TIMEOUT = &H102&
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
'Form中
Option Explicit
sub RunExe(FileName as string)
Dim pId As Long, pHnd As Long, ret
pId = Shell(FileName, vbNormalFocus)
pHnd = OpenProcess(SYNCHRONIZE, 0, pId)
If pHnd <> 0 Then
Do
ret = WaitForSingleObject(pHnd, 0)
DoEvents
Loop While ret = WAIT_TIMEOUT
CloseHandle pHnd
End If
End Sub
'用runexe代替shell函数,如runexe("a.bat")
㈦ 如何:创建异步 HTTP 处理程序
在异步 HTTP 处理程序的处理期间,ASP.NET 将通常用于外部进程的线程放回线程池中,直到处理程序收到来自外部进程的回调。这样可以避免阻止线程,从而提高性能,因为一次只能执行有限数量的线程。如果许多用户都在请求依赖于外部进程的同步 HTTP 处理程序,那么操作系统可能很快就会用完所有线程,因为大量线程被阻止,正在等待外部进程。下面的代码示例演示了一个异步 HTTP 处理程序,该处理程序在 ASP.NET 应用程序中处理对扩展名为 .SampleAsync 的文件的请求。该示例演示了处理程序的代码,然后演示如何将 .SampleAsync 扩展名映射到 ASP.NET 中的处理程序。最后,该示例演示如何在 IIS 中将 .SampleAsync 扩展名映射到 ASP.NET,以便 IIS 可以将以 .SampleAsync 结尾的请求转发给 ASP.NET。有关ASP.NET 运行库如何与 IIS 交互的更多信息,请参见 ASP.NET 应用程序生命周期概述。创建HelloWorldAsyncHandler HTTP 处理程序类在App_Code 目录中创建一个名为 HelloWorldAsyncHandler 的类,并向类文件中添加以下代码: Visual Basic Imports Microsoft.VisualBasic Imports System.Web Imports System.Threading PublicClass HelloWorldAsyncHandler Implements IHttpAsyncHandler PublicReadOnlyProperty IsReusable() AsBooleanImplements System.Web.IHttpHandler.IsReusable BeginProcessRequest( _ ByVal context As System.Web.HttpContext, _ ByVal cb As System.AsyncCallback, _ ByVal extraData AsObject) _ As System.IAsyncResult _ Implements System.Web.IHttpAsyncHandler.BeginProcessRequest context.Response.Write("<p>Begin IsThreadPoolThread is " _ & Thread.CurrentThread.IsThreadPoolThread & "</p>" & vbCrLf) Dim asynch AsNew AsynchOperation(cb, context, extraData) asynch.StartAsyncWork() Return asynch EndFunctionPublicSub EndProcessRequest(ByVal result As _ System.IAsyncResult) _ Implements System.Web.IHttpAsyncHandler.EndProcessRequest EndSubPublicSub ProcessRequest(ByVal context _ As System.Web.HttpContext) _ Implements System.Web.IHttpHandler.ProcessRequest ThrowNew InvalidOperationException() EndSubEndClassClass AsynchOperation Implements IAsyncResult Private _completed AsBooleanPrivate _state As [Object] Private _callback As AsyncCallback Private _context As HttpContext ReadOnlyProperty IsCompleted() AsBoolean _ Implements IAsyncResult.IsCompleted GetReturn _completed AsyncWaitHandle() As WaitHandle _ Implements IAsyncResult.AsyncWaitHandle GetReturnNothing AsyncState() As [Object] _ Implements IAsyncResult.AsyncState GetReturn _state CompletedSynchronously() AsBoolean _ Implements IAsyncResult.CompletedSynchronously (ByVal callback As AsyncCallback, _ ByVal context As HttpContext, _ ByVal state As [Object]) _callback = callback _context = context _state = state _completed = FalseEndSubPublicSub StartAsyncWork() ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf StartAsyncTask), Nothing) EndSubPrivateSub StartAsyncTask(ByVal workItemState As [Object]) _context.Response.Write("<p>Completion IsThreadPoolThread is " & Thread.CurrentThread.IsThreadPoolThread & "</p>" & vbCrLf) _context.Response.Write("Hello World from Async Handler!") _completed = True _callback(Me) EndSub 'StartAsyncTask EndClass 'AsynchOperation C# using System; using System.Web; using System.Threading; class HelloWorldAsyncHandler : IHttpAsyncHandler { publicbool IsReusable { get { returnfalse; } } public HelloWorldAsyncHandler() { } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) { context.Response.Write("<p>Begin IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n"); AsynchOperation asynch = new AsynchOperation(cb, context, extraData); asynch.StartAsyncWork(); return asynch; } publicvoid EndProcessRequest(IAsyncResult result) { } publicvoid ProcessRequest(HttpContext context) { throw new InvalidOperationException(); } } class AsynchOperation : IAsyncResult { privatebool _completed; private Object _state; private AsyncCallback _callback; private HttpContext _context; bool IAsyncResult.IsCompleted { get { return _completed; } } WaitHandle IAsyncResult.AsyncWaitHandle { get { returnnull; } } Object IAsyncResult.AsyncState { get { return _state; } } bool IAsyncResult.CompletedSynchronously { get { returnfalse; } } public AsynchOperation(AsyncCallback callback, HttpContext context, Object state) { _callback = callback; _context = context; _state = state; _completed = false; } publicvoid StartAsyncWork() { ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null); } privatevoid StartAsyncTask(Object workItemState) { _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n"); _context.Response.Write("Hello World from Async Handler!"); _completed = true; _callback(this); } }该代码实现 BeginProcessRequest 方法。该方法向当前的 HttpContext 对象的 Response 属性中写入一个字符串,创建一个 AsyncOperation 类的新实例,然后调用 StartAsyncWork 方法。然后,StartAsyncWork 方法向 ThreadPool 对象添加 StartAsyncTask 委托。当有线程可用时,将调用 StartAsyncTask 方法,该方法向 Response 属性写出另外一个字符串,然后通过调用 AsyncCallback 委托完成该任务。 注册自定义 HTTP 处理程序在创建了自定义 HTTP 处理程序类之后,必须在 Web.config 文件中注册该类,以便由 ASP.NET 来处理对带有 .SampleAsync 扩展名的文件的请求。在Web.config 文件中注册自定义 HTTP 处理程序如果您的网站没有 Web.config 文件,请创建一个 Web.config 文件。向Web.config 文件添加下面的代码:<configuration> <system.web> <httpHandlers> <add verb="*" path="*.SampleAsync" type="HelloWorldAsyncHandler"/> </httpHandlers> </system.web> </configuration>该代码将 HelloWorldAsyncHandler 处理程序注册为对以 .SampleAsync 结尾的请求的处理程序。为HTTP 处理程序扩展名配置 IISIIS 只将针对某些文件类型的请求传递给 ASP.NET 进行处理。默认情况下,具有 .aspx、.ascx、.asmx 等扩展名的文件已映射到 ASP.NET,但是,如果您希望由 ASP.NET 来处理您所定义的文件扩展名,则必须在 IIS 中注册这些扩展名。有关更多信息,请参见 ASP.NET 应用程序生命周期概述。在IIS 中映射扩展名打开“Internet 服务管理器”。右击您的应用程序,然后选择“属性”。在“目录”选项卡中,单击“配置”。选择“映射”选项卡。
㈧ 关于generator异步编程的理解以及如何动手写
关于generator异步编程的理解以及如何动手写一个co模块
generator出现之前,想要实现对异步队列中任务的流程控制,大概有这么一下几种方式:
回调函数
事件监听
发布/订阅
promise对象
第一种方式想必大家是最常见的,其代码组织方式如下:
我们把函数放到run的执行器里面,便实现了同步操作异步代码的过程
㈨ 怎么使程序与sql server异步执行请达人指教!!!
这种问题我早就碰过了,使用多线程是一种非常不好的选择,你的系统随时都会崩溃。
办法其实非常简单,你只要使用ADO异步操作就可以了,完全不必建立多线程,当然这涉及ADO的高级应用,今天心情好,教你几招!(下面是我在VB中使用过的方法,DELPHI中同样也能使用ADO异步操作访问SQLSERVER)
之前先与SQL
SERVER建立一个CONNECTION对象,将其CURSORLOCATION属性设置为adUseClient
然后用ADO
CONNECTION的Execute方法异步执行存储过程即可
例如:con.CursorLocation
=
adUseClient
dim
strSQL
as
String
strSQL="SQL语句或存储过程名及其参数"
'语法必须正确
con.Execute
strSQL,
,
adAsyncExecute
'adAsyncExecute指令异步操作
这样你的应用程序就不用等待存储过程执行完毕后才可执行后续代码了。
你还可以使用ADO
CONNECTION对象的ExecuteComplete事件在执行完存储过程后
通知你的应用程序执行相应的动作,例如MSGBOX等之类的东西,具体的实现代码你自己去查ADO联机手册。
另外顺便提一下,如果对于一个执行了很长时间都未能完成的查询,你别指望使用貌似很行的ADO的CANCEL方法,立即取消一个正在执行的ADO异步操作,即使在更新版本的ADO.net
3.5也是如此(非要等到超时后才能生效),真不明白微软的工程师们是如何想的!谁要是能给出解决方法,我奖他300分,外加现金若干。
答复补充问题:
“四楼的大哥
我还想问一下
如果我在这个存储过程还没有执行完成的时候
其他客户端又调用了这个存储过程
会不会出错呢???我不太清楚一个存储过程还没有执行完的时候
是否可以再次调用
请指教
谢谢!!!!”
不会的,因为SQLSERVER引擎会处理这些并发问题(自动使用事务处理,微软的工程师们早就想到这些问题了,请放心使用)
㈩ c++socket客户端程序如何异步处理 求高手指教 能帮我切实解决问题可追加分
服务器端是你写的不,如果是,你可以客户端每次收到一条信息,然后发送一条确认信息给服务器端,然后服务器端收到确认信息后再发送第二条信息。