线程和委托-我不完全了解他们之间的关系 [英] Threads and delegates — I don't fully understand their relations

查看:158
本文介绍了线程和委托-我不完全了解他们之间的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个看起来像这样的代码:

I wrote a code that looks somewhat like this:

Thread t = new Thread(() => createSomething(dt, start, finish) );
t.Start();

它有效(有时几乎感觉到有多个线程).

And it works (sometimes it almost feel like there are multiple threads).

但是我不使用任何代表.

Yet I don't use any delegates.

  1. 没有代表的踩踏是什么意思?
  2. 如果需要委托人,请告诉我与委托人的连接方式以及建立连接的方式.

推荐答案

多线程非常复杂.您在剪切和粘贴代码时甚至没有学习任何有关线程的最基本方面的信息-如何启动线程.将网络上的某些内容粘贴到UI中以修复或调整控件是一回事.这是完全不同的过程.您需要研究该主题,编写所有自己的代码,并确切地了解其工作方式,否则您将为此浪费时间.

Multi-threading is very complex. You are cutting and pasting code without even learning anything about the most basic aspects of threading - how to start a thread. Pasting something off the web into a UI to fix or tweak a control, is one thing. This is a completely different kind of process. You need to study the subject, write all your own code, and understand exactly how it works, otherwise you are just wasting your time with this.

委托是类型安全函数指针的.NET版本.所有线程都需要一个入口点才能开始执行.根据定义,在创建主线程时,它始终运行Main()作为其入口点.您创建的所有其他线程都需要一个显式定义的入口点-指向应在其中开始执行的函数的指针.因此线程始终需要委托.

A delegate is the .NET version of a type safe function pointer. All threads require an entry point to start execution. By definition when a primary thread is created it always runs Main() as it's entry point. Any additional threads you create will need an explicitly defined entry point - a pointer to the function where they should begin execution. So threads always require a delegate.

委托也经常在线程中用于其他目的,主要是回调.如果您希望线程向后报告一些信息,例如完成状态,则一种可能性是创建该线程可以使用的回调函数.同样,线程需要一个指针才能执行回调,因此也为此使用了委托.与入口点不同,它们是可选的,但是概念是相同的.

Delegates are often used in threading for other purposes too, mainly callbacks. If you want a thread to report some information back such as completion status, one possibility is to create a callback function that the thread can use. Again the thread needs a pointer to be able to execute the callback so delegates are used for this as well. Unlike an entry point these are optional, but the concept is the same.

线程和委托之间的关系是辅助线程不能仅调用主应用程序线程之类的方法,因此需要一个函数指针,而委托则充当函数指针.

The relationship between threads and delegates is secondary threads cannot just call methods like the primary app thread, so a function pointer is needed instead and delegates act as function pointers.

您没有看到委托,也没有创建委托,因为该框架正在Thread构造函数中为您完成委托.您可以传入要用于启动线程的方法,框架代码将为您创建一个指向该方法的委托.如果要使用回调,则必须自己创建一个委托.

You do not see the delegate and you did not create one because the framework is doing it for you in the Thread constructor. You can pass in the method you want to use to start the thread, and the framework code creates a delegate that points to this method for you. If you wanted to use a callback you would have to create a delegate yourself.

这里是没有lambda表达式的代码. SomeClass的处理需要很长时间,并且是在后台线程上完成的.为了解决这个问题,已经创建了SomeThreadTask,它包含进程代码以及线程运行它所需的所有内容.线程完成后,第二个委托用于回调.

Here is code without lambda expressions. SomeClass has some processing that takes a long time and is done on background threads. To help with this the SomeThreadTask has been created, and it contains the process code and everything the thread needs to run it. A second delegate is used for a callback when the thread is done.

真实的代码会更加复杂,并且真实的类永远不必知道如何创建线程等,因此您将拥有管理器对象.

Real code would be more complicated, and a real class should never have to know how to create threads etc so you would have manager objects.

// Create a delegate for our callback function.
public delegate void SomeThreadTaskCompleted(string taskId, bool isError);


public class SomeClass
{

    private void DoBackgroundWork()
    {
        // Create a ThreadTask object.

        SomeThreadTask threadTask = new SomeThreadTask();

        // Create a task id.  Quick and dirty here to keep it simple.  
        // Read about threading and task identifiers to learn 
        // various ways people commonly do this for production code.

        threadTask.TaskId = "MyTask" + DateTime.Now.Ticks.ToString();

        // Set the thread up with a callback function pointer.

        threadTask.CompletedCallback = 
            new SomeThreadTaskCompleted(SomeThreadTaskCompletedCallback);


        // Create a thread.  We only need to specify the entry point function.
        // Framework creates the actual delegate for thread with this entry point.

        Thread thread = new Thread(threadTask.ExecuteThreadTask);

        // Do something with our thread and threadTask object instances just created
        // so we could cancel the thread etc.  Can be as simple as stick 'em in a bag
        // or may need a complex manager, just depends.

        // GO!
        thread.Start();

        // Go do something else.  When task finishes we will get a callback.

    }

    /// <summary>
    /// Method that receives callbacks from threads upon completion.
    /// </summary>
    /// <param name="taskId"></param>
    /// <param name="isError"></param>
    public void SomeThreadTaskCompletedCallback(string taskId, bool isError)
    {
        // Do post background work here.
        // Cleanup the thread and task object references, etc.
    }
}


/// <summary>
/// ThreadTask defines the work a thread needs to do and also provides any data 
/// required along with callback pointers etc.
/// Populate a new ThreadTask instance with any data the thread needs 
/// then start the thread to execute the task.
/// </summary>
internal class SomeThreadTask
{

    private string _taskId;
    private SomeThreadTaskCompleted _completedCallback;

    /// <summary>
    /// Get. Set simple identifier that allows main thread to identify this task.
    /// </summary>
    internal string TaskId
    {
        get { return _taskId; }
        set { _taskId = value; }
    }

    /// <summary>
    /// Get, Set instance of a delegate used to notify the main thread when done.
    /// </summary>
    internal SomeThreadTaskCompleted CompletedCallback
    {
        get { return _completedCallback; }
        set { _completedCallback = value; }
    }

    /// <summary>
    /// Thread entry point function.
    /// </summary>
    internal void ExecuteThreadTask()
    {
        // Often a good idea to tell the main thread if there was an error
        bool isError = false;

        // Thread begins execution here.

        // You would start some kind of long task here 
        // such as image processing, file parsing, complex query, etc.

        // Thread execution eventually returns to this function when complete.

        // Execute callback to tell main thread this task is done.
        _completedCallback.Invoke(_taskId, isError);


    }

}
}

这篇关于线程和委托-我不完全了解他们之间的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆