如何异步调用asp.net中的函数?或任何其他解决方案来达到目标​​?

发布于 2024-12-03 13:22:49 字数 2800 浏览 1 评论 0原文

该函数的目标是填写from(来自第3方网站)并单击提交按钮并获取提交结果页面的html源。此任务需要在 asp.net 中按钮的单击事件上完成。如果函数返回 true,则在最后执行一些 sql 任务。我读到了有关 asp.net 中的异步处理程序的内容,但确实是初学者,不确定在 asp.net 中模拟此类任务的最佳解决方案是什么。

Protected Sub lbtnSave_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles lbtnSave.Click
             If  CrawlWebSite() then
                'Save
             End If
         End Sub

Private Function CrawlWebSite() As Boolean
            Dim objBrowser = CreateObject("InternetExplorer.Application")
            Dim url As String = "https://test.com/Search.do?subAction=reset&searchType=ind"
            With objBrowser
                .navigate(url)
                System.Threading.Thread.Sleep(1000)

                Dim StartTime As DateTime
                Dim ElapsedTime As TimeSpan
                Dim bLong As Boolean = False
                StartTime = Now
                Do While .busy = True
                    ElapsedTime = Now().Subtract(StartTime)
                    If (ElapsedTime.TotalSeconds Mod 60) >= 55 Then
                        bLong = True
                        Exit Do
                    End If
                    System.Threading.Thread.Sleep(1000)
                Loop

                If bLong = True Then
                    PageName.Alert(Page, "There is a delay retrieving the website for checking NPI. Please try again.")
                    Return False
                End If

                .document.getElementById("lastname").Value = txtLastName.Text.Trim
                .document.getElementById("searchNpi").Value = txtUPIN.Text.Trim
                .document.getElementsByTagName("input").item(7).click()

                System.Threading.Thread.Sleep(1000)

                bLong = False
                StartTime = Now
                Do While .busy = True
                    'There is a delay retrieving the website. Continue ?
                    ElapsedTime = Now().Subtract(StartTime)
                    If (ElapsedTime.TotalSeconds Mod 60) >= 50 Then
                        bLong = True
                        Exit Do
                    End If
                    System.Threading.Thread.Sleep(1000)
                Loop

                If bLong = True Then
                    PageName.Alert(Page, "There is a delay retrieving the website. Please try again.")
                    Return False
                End If

                If .document.getElementById("lastname") Is Nothing Then
                    'We have result
                    Return True
                Else
                    PageName.Alert(Page, "Attention: No matching records found.")
                    Return False
                End If

            End With

        End Function

The goal of the function is to fill the from (from 3rd party website) and click the submit button and gets the html source of the submitted result page. This task needs to be done on click event of the button in asp.net. If the function returns true, do some sql tasks at the end. I read about the Asynchronous Handler in asp.net but really beginner of that and not sure what a best solution is to simulate this type of task in asp.net.

Protected Sub lbtnSave_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles lbtnSave.Click
             If  CrawlWebSite() then
                'Save
             End If
         End Sub

Private Function CrawlWebSite() As Boolean
            Dim objBrowser = CreateObject("InternetExplorer.Application")
            Dim url As String = "https://test.com/Search.do?subAction=reset&searchType=ind"
            With objBrowser
                .navigate(url)
                System.Threading.Thread.Sleep(1000)

                Dim StartTime As DateTime
                Dim ElapsedTime As TimeSpan
                Dim bLong As Boolean = False
                StartTime = Now
                Do While .busy = True
                    ElapsedTime = Now().Subtract(StartTime)
                    If (ElapsedTime.TotalSeconds Mod 60) >= 55 Then
                        bLong = True
                        Exit Do
                    End If
                    System.Threading.Thread.Sleep(1000)
                Loop

                If bLong = True Then
                    PageName.Alert(Page, "There is a delay retrieving the website for checking NPI. Please try again.")
                    Return False
                End If

                .document.getElementById("lastname").Value = txtLastName.Text.Trim
                .document.getElementById("searchNpi").Value = txtUPIN.Text.Trim
                .document.getElementsByTagName("input").item(7).click()

                System.Threading.Thread.Sleep(1000)

                bLong = False
                StartTime = Now
                Do While .busy = True
                    'There is a delay retrieving the website. Continue ?
                    ElapsedTime = Now().Subtract(StartTime)
                    If (ElapsedTime.TotalSeconds Mod 60) >= 50 Then
                        bLong = True
                        Exit Do
                    End If
                    System.Threading.Thread.Sleep(1000)
                Loop

                If bLong = True Then
                    PageName.Alert(Page, "There is a delay retrieving the website. Please try again.")
                    Return False
                End If

                If .document.getElementById("lastname") Is Nothing Then
                    'We have result
                    Return True
                Else
                    PageName.Alert(Page, "Attention: No matching records found.")
                    Return False
                End If

            End With

        End Function

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

煮茶煮酒煮时光 2024-12-10 13:22:49

以下是使用 HttpHandler 实现长轮询时使用的一些类。我使用此解决方案来处理需要很长时间才能完成的操作。基本上有6个类(见下文)。其中一些课程可能最终对于您的目的来说是不需要的,但它们对我来说是有意义的。这些已“大部分”为您进行了消毒。

  1. 控制器:处理创建有效响应所需的操作(数据库操作等)
  2. 处理器:管理与网页(本身)的异步通信
  3. IAsynchProcessor :服务处理实现此接口的实例
  4. Service:处理实现 IAsynchProcessor 的请求对象
  5. Request:包含您的响应(对象)的 IAsynchProcessor 包装器
  6. 响应:包含自定义对象或字段

如果您需要有关 JavaScript 或 HTML 插件的帮助,请在下面的评论中...我将为您写一些内容。

HTTP 处理程序:

using System;
using System.Configuration;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.SessionState;

namespace Concept.LongPolling.Handlers
{
    /// <summary>
    /// Summary description for Controller
    /// </summary>
    public class Controller : IHttpHandler, IReadOnlySessionState
    {
        #region CONSTRUCTORS
        #endregion

        #region PROPERTIES

        /// <summary>Gets a Boolean value indicating that another request can use the current instance of the DefaultHttpHandler class.</summary>
        /// <remarks>Returning true makes the same AsyncHttpHandler object be used for all requests.</remarks>
        /// <remarks>Returning false here makes ASP.Net create object per request.</remarks>
        public bool IsReusable { get { return true; } }

        #endregion

        #region METHODS

        /// <summary>Enables synchronous processing of HTTP Web requests</summary>
        /// <param name="context">An HttpContext object that provides references to the intrinsic server objects</param>
        /// /// <remarks>This is where you would send commands to the controller that would affect processing in some manner.</remarks>
        public void ProcessRequest(HttpContext context)
        {
            throw new NotImplementedException();
        }

        /// <summary>Creates the response object which is serialized back to the client</summary>
        /// <param name="response"></param>
        public static Response CreateResponse(Response response)
        {
            try
            {
                response.Generate();
            }
            catch (System.Exception ex)
            {
                response.SessionValid = false;
            }

            return response;
        }

        #endregion
    }
}

using System;
using System.Configuration;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.SessionState;
using Concept.LongPolling.LongPolling;

namespace Concept.LongPolling.Handlers
{
    /// <summary>
    /// Summary description for Processor
    /// </summary>
    public class Processor : IHttpHandler, IHttpAsyncHandler, IReadOnlySessionState
    {
        #region CONSTRUCTORS
        #endregion

        #region PROPERTIES

        /// <summary>Gets a Boolean value indicating that another request can use the current instance of the DefaultHttpHandler class.</summary>
        /// <remarks>Returning true makes the same AsyncHttpHandler object be used for all requests.</remarks>
        /// <remarks>Returning false here makes ASP.Net create object per request.</remarks>
        public bool IsReusable { get { return false; } }

        #endregion

        #region METHODS

        /// <summary>Enables synchronous processing of HTTP Web requests</summary>
        /// <param name="context">An HttpContext object that provides references to the intrinsic server objects</param>
        public void ProcessRequest(HttpContext context)
        {
            throw new NotImplementedException();
        }

        #region IHttpAsyncHandler Members

        /// <summary>Enables asynchronous processing of HTTP Web requests</summary>
        /// <param name="context">An HttpContext object that provides references to the intrinsic server objects</param>
        /// <param name="cb">The method to call when the asynchronous method call is complete. If callback is null, the delegate is not called.</param>
        /// <param name="extraData"></param>
        /// <returns>Any state data that is needed to process the request.</returns>
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            Int32 someValueYouLikeToSendInYourClass = Convert.ToInt32(context.Request["Number"]);

            Request request = new Request(cb, context);
            request.Response.Number = someValueYouLikeToSendInYourClass;

            Service.Singleton.AddRequest(request);

            return request;
        }

        /// <summary>Provides an end method for an asynchronous process.</summary>
        /// <param name="result">An object that contains information about the status of the process.</param>
        public void EndProcessRequest(IAsyncResult result)
        {
            Request request = result as Request;
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            request.HttpContext.Response.ContentType = "text/json";
            request.HttpContext.Response.Write(serializer.Serialize(request.Response));
            request.HttpContext.Response.End();
        }

        #endregion

        #endregion
    }
}

支持类:

using System;
using System.Runtime.InteropServices;

namespace Concept.LongPolling.LongPolling
{
    /// <summary>Represents the executable instance of an asynchronous operation.</summary>
    [ComVisible(true)]
    public interface IAsynchProcessor : IAsyncResult
    {
        /// <summary>
        /// Gets a value that indicates whether the operation completed sucessfully.
        /// </summary>
        /// <returns>true if the operation completed sucessfully; otherwise, false.</returns>
        bool ProcessRequest();
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;

namespace Concept.LongPolling.LongPolling
{
    public sealed class Service
    {
        #region CONSTRUCTORS

        private Service()
        {
            requests = new List<IAsynchProcessor>();
            backgroundThread = new Thread(new ThreadStart(MainLoop));
            backgroundThread.IsBackground = true;
            backgroundThread.Start();
        }

        #endregion

        #region PROPERTIES

        private static Service singleton;
        private Thread backgroundThread;
        private List<IAsynchProcessor> requests;
        static readonly object padlock = new object();

        public static Service Singleton
        {
            get
            {
                if (_singleton == null)
                    lock (_padlock)
                    {
                        if (_singleton == null)
                            _singleton = new Service();
                    }

                return _singleton;
            }
        }

        #endregion

        #region METHODS

        private void MainLoop()
        {
            while (true)
            {
                foreach (IAsynchProcessor request in requests.ToArray())
                {
                    if (request.ProcessRequest())
                        requests.Remove(request);
                }
                Thread.Sleep(500);
            }
        }

        public void AddRequest(IAsynchProcessor request)
        {
            lock (padlock)
            {
                requests.Add(request);
            }
        }

        #endregion
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Concept.LongPolling.Business;
using System.Data;

namespace Concept.LongPolling.Handlers
{
    public class Response
    {
        #region CONSTRUCTORS

        public Response()
        {
            SessionValid = true;
            Exception = String.Empty;
        }

        #endregion

        #region PROPERTIES

        public const int TimeOffset = 120;

        public Int32 Number { get; set; }
        public bool SessionValid { get; set; }
        public String Exception { get; set; }

        #endregion

        #region METHODS

        public void Generate()
        {
            // do some desired operation
            Number += 1;
        }

        #endregion
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Concept.LongPolling.LongPolling;

namespace Concept.LongPolling.Handlers
{
    public class Request : IAsynchProcessor
    {
        #region CONSTRUCTORS

        public Request(AsyncCallback callback, HttpContext context)
        {
            asyncCallback = callback;
            httpContext = context;
            createdTime = DateTime.Now;

            Response = new Response();
        }

        #endregion

        #region PROPERTIES

        public const int TimeoutSeconds = 15;

        private AsyncCallback asyncCallback;
        private HttpContext httpContext;
        private DateTime createdTime;

        public bool TimedOut
        {
            get
            {
                return ((DateTime.Now - createdTime).TotalSeconds >= TimeoutSeconds);
            }
        }

        public Response Response { get; set; }

        #region IAsyncResult Members

        public HttpContext HttpContext
        {
            get
            {
                return httpContext;
            }
        }
        public object AsyncState { get; set; }

        System.Threading.WaitHandle IAsyncResult.AsyncWaitHandle
        {
            get { throw new NotImplementedException(); }
        }

        bool IAsyncResult.CompletedSynchronously
        {
            get { return false; }
        }

        public bool IsCompleted
        {
            get { return isCompleted; }
            set
            {
                if (!value) return;

                this.isCompleted = true;
                asyncCallback(this);
            }
        }
        bool isCompleted = false;

        #endregion

        #endregion

        #region METHODS

        public bool ProcessRequest()
        {
            this.Response = Controller.CreateResponse(this.Response);
            this.IsCompleted = true;

            return this.IsCompleted;
        }

        #endregion
    }
}

Here are some classes used in implementing long-polling using HttpHandlers. I use this solution for operations that take a LONG time to finish. There are basically 6 classes (see below). Some of these classes may end-up being unneeded for YOUR purposes, but they made sense for mine. These have "mostly" been sanitized for you.

  1. Controller: Processes actions required to create a valid response (db operations etc.)
  2. Processor: Manages asynch communication with the web page (itself)
  3. IAsynchProcessor: The service processes instances that implement this interface
  4. Sevice: Processes request objects that implement IAsynchProcessor
  5. Request: The IAsynchProcessor wrapper containing your response (object)
  6. Response: Contains custom objects or fields

If you need help with the JavaScript or HTML add-in a comment below...I will write something for you.

HTTP HANDLERS:

using System;
using System.Configuration;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.SessionState;

namespace Concept.LongPolling.Handlers
{
    /// <summary>
    /// Summary description for Controller
    /// </summary>
    public class Controller : IHttpHandler, IReadOnlySessionState
    {
        #region CONSTRUCTORS
        #endregion

        #region PROPERTIES

        /// <summary>Gets a Boolean value indicating that another request can use the current instance of the DefaultHttpHandler class.</summary>
        /// <remarks>Returning true makes the same AsyncHttpHandler object be used for all requests.</remarks>
        /// <remarks>Returning false here makes ASP.Net create object per request.</remarks>
        public bool IsReusable { get { return true; } }

        #endregion

        #region METHODS

        /// <summary>Enables synchronous processing of HTTP Web requests</summary>
        /// <param name="context">An HttpContext object that provides references to the intrinsic server objects</param>
        /// /// <remarks>This is where you would send commands to the controller that would affect processing in some manner.</remarks>
        public void ProcessRequest(HttpContext context)
        {
            throw new NotImplementedException();
        }

        /// <summary>Creates the response object which is serialized back to the client</summary>
        /// <param name="response"></param>
        public static Response CreateResponse(Response response)
        {
            try
            {
                response.Generate();
            }
            catch (System.Exception ex)
            {
                response.SessionValid = false;
            }

            return response;
        }

        #endregion
    }
}

using System;
using System.Configuration;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.SessionState;
using Concept.LongPolling.LongPolling;

namespace Concept.LongPolling.Handlers
{
    /// <summary>
    /// Summary description for Processor
    /// </summary>
    public class Processor : IHttpHandler, IHttpAsyncHandler, IReadOnlySessionState
    {
        #region CONSTRUCTORS
        #endregion

        #region PROPERTIES

        /// <summary>Gets a Boolean value indicating that another request can use the current instance of the DefaultHttpHandler class.</summary>
        /// <remarks>Returning true makes the same AsyncHttpHandler object be used for all requests.</remarks>
        /// <remarks>Returning false here makes ASP.Net create object per request.</remarks>
        public bool IsReusable { get { return false; } }

        #endregion

        #region METHODS

        /// <summary>Enables synchronous processing of HTTP Web requests</summary>
        /// <param name="context">An HttpContext object that provides references to the intrinsic server objects</param>
        public void ProcessRequest(HttpContext context)
        {
            throw new NotImplementedException();
        }

        #region IHttpAsyncHandler Members

        /// <summary>Enables asynchronous processing of HTTP Web requests</summary>
        /// <param name="context">An HttpContext object that provides references to the intrinsic server objects</param>
        /// <param name="cb">The method to call when the asynchronous method call is complete. If callback is null, the delegate is not called.</param>
        /// <param name="extraData"></param>
        /// <returns>Any state data that is needed to process the request.</returns>
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            Int32 someValueYouLikeToSendInYourClass = Convert.ToInt32(context.Request["Number"]);

            Request request = new Request(cb, context);
            request.Response.Number = someValueYouLikeToSendInYourClass;

            Service.Singleton.AddRequest(request);

            return request;
        }

        /// <summary>Provides an end method for an asynchronous process.</summary>
        /// <param name="result">An object that contains information about the status of the process.</param>
        public void EndProcessRequest(IAsyncResult result)
        {
            Request request = result as Request;
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            request.HttpContext.Response.ContentType = "text/json";
            request.HttpContext.Response.Write(serializer.Serialize(request.Response));
            request.HttpContext.Response.End();
        }

        #endregion

        #endregion
    }
}

SUPPORTING CLASSES:

using System;
using System.Runtime.InteropServices;

namespace Concept.LongPolling.LongPolling
{
    /// <summary>Represents the executable instance of an asynchronous operation.</summary>
    [ComVisible(true)]
    public interface IAsynchProcessor : IAsyncResult
    {
        /// <summary>
        /// Gets a value that indicates whether the operation completed sucessfully.
        /// </summary>
        /// <returns>true if the operation completed sucessfully; otherwise, false.</returns>
        bool ProcessRequest();
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;

namespace Concept.LongPolling.LongPolling
{
    public sealed class Service
    {
        #region CONSTRUCTORS

        private Service()
        {
            requests = new List<IAsynchProcessor>();
            backgroundThread = new Thread(new ThreadStart(MainLoop));
            backgroundThread.IsBackground = true;
            backgroundThread.Start();
        }

        #endregion

        #region PROPERTIES

        private static Service singleton;
        private Thread backgroundThread;
        private List<IAsynchProcessor> requests;
        static readonly object padlock = new object();

        public static Service Singleton
        {
            get
            {
                if (_singleton == null)
                    lock (_padlock)
                    {
                        if (_singleton == null)
                            _singleton = new Service();
                    }

                return _singleton;
            }
        }

        #endregion

        #region METHODS

        private void MainLoop()
        {
            while (true)
            {
                foreach (IAsynchProcessor request in requests.ToArray())
                {
                    if (request.ProcessRequest())
                        requests.Remove(request);
                }
                Thread.Sleep(500);
            }
        }

        public void AddRequest(IAsynchProcessor request)
        {
            lock (padlock)
            {
                requests.Add(request);
            }
        }

        #endregion
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Concept.LongPolling.Business;
using System.Data;

namespace Concept.LongPolling.Handlers
{
    public class Response
    {
        #region CONSTRUCTORS

        public Response()
        {
            SessionValid = true;
            Exception = String.Empty;
        }

        #endregion

        #region PROPERTIES

        public const int TimeOffset = 120;

        public Int32 Number { get; set; }
        public bool SessionValid { get; set; }
        public String Exception { get; set; }

        #endregion

        #region METHODS

        public void Generate()
        {
            // do some desired operation
            Number += 1;
        }

        #endregion
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Concept.LongPolling.LongPolling;

namespace Concept.LongPolling.Handlers
{
    public class Request : IAsynchProcessor
    {
        #region CONSTRUCTORS

        public Request(AsyncCallback callback, HttpContext context)
        {
            asyncCallback = callback;
            httpContext = context;
            createdTime = DateTime.Now;

            Response = new Response();
        }

        #endregion

        #region PROPERTIES

        public const int TimeoutSeconds = 15;

        private AsyncCallback asyncCallback;
        private HttpContext httpContext;
        private DateTime createdTime;

        public bool TimedOut
        {
            get
            {
                return ((DateTime.Now - createdTime).TotalSeconds >= TimeoutSeconds);
            }
        }

        public Response Response { get; set; }

        #region IAsyncResult Members

        public HttpContext HttpContext
        {
            get
            {
                return httpContext;
            }
        }
        public object AsyncState { get; set; }

        System.Threading.WaitHandle IAsyncResult.AsyncWaitHandle
        {
            get { throw new NotImplementedException(); }
        }

        bool IAsyncResult.CompletedSynchronously
        {
            get { return false; }
        }

        public bool IsCompleted
        {
            get { return isCompleted; }
            set
            {
                if (!value) return;

                this.isCompleted = true;
                asyncCallback(this);
            }
        }
        bool isCompleted = false;

        #endregion

        #endregion

        #region METHODS

        public bool ProcessRequest()
        {
            this.Response = Controller.CreateResponse(this.Response);
            this.IsCompleted = true;

            return this.IsCompleted;
        }

        #endregion
    }
}
冧九 2024-12-10 13:22:49

看一下这篇文章,它描述了如何异步执行方法,并使用在异步方法调用完成时触发的事件处理程序。

http://www.csharp-examples.net/create-asynchronous-method/

以下是如何将本文内容应用到您的情况的草稿。我还没有测试过代码,所以它可能不完美,但应该很接近。

您需要导入以下命名空间:

using System.Threading;
using System.ComponentModel;
using System.Runtime.Remoting.Messaging;

这是粗略的实现:

//boolean flag which indicates whether the async task is running
private bool crawling = false;

private delegate bool CrawlWebsiteDelegate();

private bool CrawlWebsite()
{
    //crawl the website

    return false;
}

protected void Button1_Click(object sender, EventArgs e)
{
    CrawlWebsiteDelegate worker = new CrawlWebsiteDelegate(CrawlWebsite);
    AsyncCallback completedCallback = new AsyncCallback(CrawlWebsiteCompletedCallback);

    if (!crawling)
    {
        worker.BeginInvoke(completedCallback, AsyncOperationManager.CreateOperation(null));
        crawling = true;
    }
}

private void CrawlWebsiteCompletedCallback(IAsyncResult ar)
{
    //get the original worker delegate and the AsyncOperation instance
    CrawlWebsiteDelegate worker = (CrawlWebsiteDelegate)((AsyncResult)ar).AsyncDelegate;

    //finish the asynchronous operation
    bool success = worker.EndInvoke(ar);
    crawling = false;

    if (success)
    {
        //perform sql tasks now that crawl has completed
    }
}

编辑:这是 VB.NET 中的代码 - 并不肯定所有语法都正确

Private crawling As Boolean = False    
Private Delegate Function CrawlWebsiteDelegate() As Boolean

Private Function CrawlWebsite() As Boolean
    Return False    
End Function

Protected Sub Button1_Click(sender As Object, e As EventArgs)
    Dim worker As New CrawlWebsiteDelegate(AddressOf CrawlWebsite)
    Dim completedCallback As New AsyncCallback(AddressOf CrawlWebsiteCompletedCallback) 
    If Not crawling Then
        worker.BeginInvoke(completedCallback, AsyncOperationManager.CreateOperation(Nothing))
        crawling = True
    End If  
End Sub

Private Sub CrawlWebsiteCompletedCallback(ar As IAsyncResult)
    Dim worker As CrawlWebsiteDelegate = DirectCast(DirectCast(ar, AsyncResult).AsyncDelegate, CrawlWebsiteDelegate)
    Dim success As Boolean = worker.EndInvoke(ar)
    crawling = False        
    If success Then
        DoSomeSqlTasks()
    End If
End Sub

Take a look at this article, which describes how to execute a method asynchronously, and uses an event handler that fires when the asynchronous method call has completed.

http://www.csharp-examples.net/create-asynchronous-method/

Here's a rough draft of how you would apply the contents of the article in your situation. I haven't tested the code, so it might not be perfect, but it should be close.

You need to import the following namespaces:

using System.Threading;
using System.ComponentModel;
using System.Runtime.Remoting.Messaging;

And here is the rough implementation:

//boolean flag which indicates whether the async task is running
private bool crawling = false;

private delegate bool CrawlWebsiteDelegate();

private bool CrawlWebsite()
{
    //crawl the website

    return false;
}

protected void Button1_Click(object sender, EventArgs e)
{
    CrawlWebsiteDelegate worker = new CrawlWebsiteDelegate(CrawlWebsite);
    AsyncCallback completedCallback = new AsyncCallback(CrawlWebsiteCompletedCallback);

    if (!crawling)
    {
        worker.BeginInvoke(completedCallback, AsyncOperationManager.CreateOperation(null));
        crawling = true;
    }
}

private void CrawlWebsiteCompletedCallback(IAsyncResult ar)
{
    //get the original worker delegate and the AsyncOperation instance
    CrawlWebsiteDelegate worker = (CrawlWebsiteDelegate)((AsyncResult)ar).AsyncDelegate;

    //finish the asynchronous operation
    bool success = worker.EndInvoke(ar);
    crawling = false;

    if (success)
    {
        //perform sql tasks now that crawl has completed
    }
}

EDIT: Here is the code in VB.NET - not positive that all syntax is correct

Private crawling As Boolean = False    
Private Delegate Function CrawlWebsiteDelegate() As Boolean

Private Function CrawlWebsite() As Boolean
    Return False    
End Function

Protected Sub Button1_Click(sender As Object, e As EventArgs)
    Dim worker As New CrawlWebsiteDelegate(AddressOf CrawlWebsite)
    Dim completedCallback As New AsyncCallback(AddressOf CrawlWebsiteCompletedCallback) 
    If Not crawling Then
        worker.BeginInvoke(completedCallback, AsyncOperationManager.CreateOperation(Nothing))
        crawling = True
    End If  
End Sub

Private Sub CrawlWebsiteCompletedCallback(ar As IAsyncResult)
    Dim worker As CrawlWebsiteDelegate = DirectCast(DirectCast(ar, AsyncResult).AsyncDelegate, CrawlWebsiteDelegate)
    Dim success As Boolean = worker.EndInvoke(ar)
    crawling = False        
    If success Then
        DoSomeSqlTasks()
    End If
End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文