㈠ 如何寫一個「非同步函數」
我們平常編程寫的函數 幾乎都是同步調用函數,那麼我們如何寫一個非同步執行的函數呢?!我想這個問題也許是哪些比較喜歡專研的程序員或者具有專研精神的人士回提出的問題吧!我們很多人已經習慣了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客戶端程序如何非同步處理 求高手指教 能幫我切實解決問題可追加分
伺服器端是你寫的不,如果是,你可以客戶端每次收到一條信息,然後發送一條確認信息給伺服器端,然後伺服器端收到確認信息後再發送第二條信息。