【问题标题】:background/Asynchronous process using Threading or Delegate使用线程或委托的后台/异步进程
【发布时间】:2013-07-08 08:35:26
【问题描述】:

在我的网站上
1. 填写表格后在 SQL 数据库中插入该记录
2. 在下一行中,我获取一些类对象,然后发送到与其他记录匹配
3.在匹配应用程序中花费了很多时间

现在我决定使用线程或委托将匹配过程置于后台/异步中

我以前的代码是:
1.在数据库中插入所有信息 objclsBbDAL.InsertAcquirePrvider(objAcqProvBL);

2. Matching related record with other record in database
            clsMatchMakingDAL objclsMatchMakingDAL = new clsMatchMakingDAL();
            objclsMatchMakingDAL.AcquireMatch(objAcqProvBL);  

Q 1. 哪一种是在后台/异步运行进程的最佳方式 - 线程或委托

现在我正在使用线程:

objclsBbDAL.InsertAcquirePrvider(objAcqProvBL);
//Threading
CallMatchMakingOnDiffThread(objAcqProvBL);

private void CallMatchMakingOnDiffThread(clsAcquireProviderBL objAcqPro)
{
    clsMatchMakingDAL objclsMatchMakingDAL = new clsMatchMakingDAL();
    Thread objThread = new Thread(() => objclsMatchMakingDAL.AcquireMatch(objAcqPro));
    objThread.Start();
}

第二季度。 如何使用 Delegate 完成这项任务?

【问题讨论】:

    标签: c# asp.net multithreading delegates


    【解决方案1】:

    委托就像回调,您使用它们来通知异步任务已完成,这意味着线程需要调用一个事件,该事件应该有一个委托挂钩。

    例如:

    public struct ThreadData
    {
        public int handle;
        public string details;
        public ThreadData(int handle, string details)
        {
            this.handle = handle;
            this.details = details;
        }
    }
    public class ThreadWorker
    {
        private List<Thread> threads = new List<Thread>();
        public int BeginAsyncWork(string details)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(ThreadMethod));
            threads.Add(thread);
            thread.Start(new ThreadData(threads.Count - 1, details));
            return threads.Count - 1;
        }
        private void ThreadMethod(object parameter)
        {
            ThreadData data = (ThreadData)parameter;
            Console.WriteLine(data.details);
            if (ThreadFinished != null) { ThreadFinished(data.handle); }
        }
        public delegate void ThreadEndDelegate(int handle);
        public event ThreadEndDelegate ThreadFinished;
    }
    public static class Program
    {
        private static int[] handles;
        public static void Main()
        {
            handles = new int[4];
            ThreadWorker worker = new ThreadWorker();
            worker.ThreadFinished += new ThreadWorker.ThreadEndDelegate(OnThreadFinished);
            for (int i = 0; i < 4; i++)
            {
                handles[i] = worker.BeginAsyncWork("working: " + i);
            }
            Console.ReadKey();
        }
        private static void OnThreadFinished(int handle)
        {
            Console.WriteLine("thread: " + handle + " finished");
            handles[handle] = 0;
        }
    }
    

    它很冗长,但它允许完全控制你的线程。

    编辑:

    未经测试的代码。我能想到的最短的解决方案。

    objclsBbDAL.InsertAcquirePrvider(objAcqProvBL);
    //Threading
    CallMatchMakingOnDiffThread(objAcqProvBL);
    
    private void OnMatchAcquired(object match)
    {
    //do work with found match
    }
    private event Action<object> MatchAcquired = new Action<object>(OnMatchAcquired);
    
    private void CallMatchMakingOnDiffThread(clsAcquireProviderBL objAcqPro)
    {
        clsMatchMakingDAL objclsMatchMakingDAL = new clsMatchMakingDAL();
        Thread objThread = new Thread(
    () => object match = (object)objclsMatchMakingDAL.AcquireMatch(objAcqPro); if(ThreadComplete!=nil){MatchAcquired(match);}
    );
        objThread.Start();
    }
    

    【讨论】:

    • 这是一个带委托的线程示例。我猜你的答案不是他要求的。但他的问题也是出于误解。
    • 嗯,至少它给了我一些线程练习。忘记了事件线程设计的设置有多尴尬。
    • 这很好..但是我知道什么短代码我们可以在 3-4 行代码中做到这一点..
    • 我的简单问题是我想把我的配对任务异步。我通过使用 Threading ...1 做到了。我该如何使用 Delegate ? 2. 哪个快 - 线程或委托
    • 线程和委托是两个完全不同的东西! codeproject.com/Articles/11541/…
    【解决方案2】:

    您不能仅使用委托进行后台处理。 委托与线程或异步进程完全不同。 您可以将委托理解为指向函数的指针。 线程使用委托来执行某个功能,但单独的委托并不是任何类型的后台执行。 执行您上面提到的操作将在后台运行该过程,但是您必须知道在后台运行该操作的成本以及以这种方式运行的成本。您还需要知道它是真的需要在后台运行还是只需要优化。

    【讨论】:

    • 我怎样才能对委托做同样的事情?我使用 Threading 做了什么?
    • 线程 objThread = new Thread(() => objclsMatchMakingDAL.AcquireMatch(objAcqPro)); “() => objclsMatchMakingDAL.AcquireMatch(objAcqPro)”部分是您为线程提供委托的地方。
    • 嗨 Siraj ....你的意思是 ........new Thread(delegate() { objclsMatchMakingDAL.AcquireMatch(objAcqPro)} );
    • @KrantiSingh 正是您提供委托的方式,您在那里编写的实现也是委托提供者,但语法不同。我重申,委托只是指向函数的安全指针。
    【解决方案3】:

    最简单的方法(至少对我而言)是使用委托和 BeginInvoke,它会立即返回,并且您可以提供一个在委托完成时执行的回调。 有关MSDN 的更多信息。

    在您的示例代码中,我没有看到您需要在操作完成时收到通知,以便您可以执行以下操作:

    new Action(() =>
    {
        clsMatchMakingDAL objclsMatchMakingDAL = new clsMatchMakingDAL();
        objclsMatchMakingDAL.AcquireMatch(objAcqPro);
    }).BeginInvoke(null, null);
    

    这将在 .Net 为您管理的另一个线程上执行匹配功能。如果您需要在完成时收到通知,那么BeginInvoke 调用的第一个参数可以是另一个处理完成事件的委托。

    【讨论】:

      最近更新 更多