[英]cancel async task using cancellationtoken
我希望Web應用程序的用戶能夠取消服務器端長期運行的SQL查詢(通過使用xhr.abort()
方法)
我正在使用Response.ClientDisconnectedToken
在服務器端捕獲用戶取消請求的事件(來自此處: https : //stackoverflow.com/a/17713153/8790102 )
SQL查詢例程是通過async
方法完成的(來自此處: https : //stackoverflow.com/a/24834029/8790102 )
private async Task<DataTable> executeSelectQueryAsync(string SQL, Dictionary<string, object> BindObject = null)
{
// This cancellationToken is tripped when the client abort the request
CancellationToken canceltk = HttpContext.Current.Response.ClientDisconnectedToken; // Require IIS 7.5
DataTable dt = new DataTable();
// Only line to be logged in the server
File.AppendAllText(System.Web.HttpContext.Current.Server.MapPath("~/data/logCanceledRequest.txt"), "CANCELING ENABLED" + Environment.NewLine);
try
{
dt = await Task.Run(() =>
{
// If token is canceled, cancel SQL query
canceltk.Register(() =>
{
File.AppendAllText(System.Web.HttpContext.Current.Server.MapPath("~/data/logCanceledRequest.txt"), "CANCELLING..." + Environment.NewLine);
// scmd is of type OracleCommand
if (scmd.Connection.State == ConnectionState.Open)
scmd.Cancel();
});
// Open the connection, execute the SQL command using OracleDataAdapter.Fill method and return a DataTable
return executeSelectQuery_inner(SQL, BindObject);
}, canceltk);
}
catch (TaskCanceledException ex)
{
try
{
File.AppendAllText(System.Web.HttpContext.Current.Server.MapPath("~/data/logCanceledRequest.txt"), "Cancelling query..." + Environment.NewLine);
if(scmd.Connection.State == ConnectionState.Open)
scmd.Cancel();
}
catch (Exception ex1)
{
File.AppendAllText(System.Web.HttpContext.Current.Server.MapPath("~/data/logCanceledRequest.txt"), "Cancel_ERROR:" + ex1.ToString() + Environment.NewLine);
}
}
catch (Exception ex)
{
File.AppendAllText(System.Web.HttpContext.Current.Server.MapPath("~/data/logCanceledRequest.txt"), "OTHER EXCEPTION:" + ex.ToString() + Environment.NewLine);
}
return dt;
}
我的問題是中止請求時,不會調用在canceltk.Register()
注冊的方法canceltk.Register()
未記錄相應的文本“ CANCELLING ...”)。
實際上,根本沒有記錄任何文本。 我不知道為什么。
如果在調用executeSelectQueryAsync
之前使用Thread.Sleep(5000)
並在這5秒鍾內中止請求,則TaskCanceledException
被成功引發並捕獲。
Task.Run
計划在不受AS.NET同步上下文控制的線程池線程上執行該代碼。 這就是HttpContext.Current
為null的原因。
除此之外,在這種情況下, Task.Run
導致將請求的執行轉移到另一個線程池線程,請求處理線程(另一個線程池線程)返回到池中,並且當Task.Run
完成執行時,該線程為返回到線程池線程,並檢索另一個線程並填充請求處理數據。 您只是使用了更多資源而沒有收益。 恰恰相反。
轉義ASP.NET上下文的代碼不應依賴它。
Oracle提供程序不支持異步操作嗎?
該方法實際上被很好地調用,但是System.Web.HttpContext.Current
然后具有空值,導致未捕獲到異常。
通過替換為System.Web.Hosting.HostingEnvironment.MapPath
,代碼可以成功運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.