线程和代表 - 我完全不了解他们的关系 [英] Threads and delegates - I dont fully understand their relations

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

问题描述

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

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

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



但我不使用任何代表。


  1. 没有代理人的意思是什么? / li>
  2. 如果需要委托 - 那么请告诉我与代表的连接以及如何进行。


解决方案

多线程非常复杂。您正在剪切和粘贴代码,甚至不了解线程最基本的方面 - 如何启动线程。将某些东西从Web上粘贴到UI中以修复或调整控件是一回事。这是一个完全不同的过程。你需要学习这个主题,编写你自己的所有代码,并准确了解它的工作原理,否则你只是在浪费你的时间。



代表是。 NET版的一种类型的安全功能指针。所有线程都需要一个入口点才能开始执行。根据创建主线程的定义,它总是运行Main()作为入口点。您创建的任何其他线程将需要一个明确定义的入口点 - 指向应该开始执行的函数的指针。所以线程总是需要一个代理人。



代理人通常用于线程用于其他目的,主要是回调。如果你想要一个线程报告一些信息,如完成状态,一个可能的方法是创建线程可以使用的回调函数。线程再次需要一个指针,以便能够执行回调,所以委托也被用于此。与入门点不同,这些是可选的,但概念是一样的。



线程和委托之间的关系是辅助线程不能只调用主应用程序线程的方法,所以需要一个函数指针,代理作为函数指针。



你没有看到代理,你没有创建一个,因为框架是为你在线程构造函数。您可以传递要用于启动线程的方法,而框架代码会为您创建一个指向此方法的代理。如果你想使用回调,你将不得不自己创建一个委托。



这里是没有lambda表达式的代码。 SomeClass有一些处理需要很长时间,并且在后台线程上完成。为了帮助这个,已经创建了SomeThreadTask,它包含进程代码和线程需要运行的一切。当线程完成时,第二个代理用于回调。



真正的代码会更复杂,一个真正的类不应该知道如何创建线程等所以你会有经理对象。

  //为我们的回调函数创建代理。 
public delegate void SomeThreadTaskCompleted(string taskId,bool isError);


public class SomeClass
{

private void DoBackgroundWork()
{
//创建一个ThreadTask对象。

SomeThreadTask threadTask = new SomeThreadTask();

//创建任务ID。在这里快速和脏,保持简单。
//阅读有关线程和任务标识符以学习
//人们通常为生产代码执行的各种方式。

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

//使用回调函数指针设置线程。

threadTask.CompletedCallback =
new SomeThreadTaskCompleted(SomeThreadTaskCompletedCallback);


//创建一个线程。我们只需要指定入口点函数。
//框架创建具有此入口点的线程的实际委托。

线程线程=新线程(threadTask.ExecuteThreadTask);

//用我们的线程和threadTask对象实例做一些事情刚刚创建
//所以我们可以取消线程等可以像一个包里的贴子一样简单
//或者可能需要一个复杂的经理,只是依赖。

// GO!
thread.Start();

//去做别的事当任务完成时,我们将得到一个回调。

}

///< summary>
///完成后从线程接收回调的方法。
///< / summary>
///< param name =taskId>< / param>
///< param name =isError>< / param>
public void SomeThreadTaskCompletedCallback(string taskId,bool isError)
{
//在这里发布后台工作。
//清理线程和任务对象引用等
}
}


///< summary>
/// ThreadTask定义线程需要做的工作,并提供任何数据
///与回调指针等一起。
///使用任何数据填充一个新的ThreadTask实例线程需要
///然后启动线程来执行任务。
///< / summary>
内部类SomeThreadTask
{

私有字符串_taskId;
private SomeThreadTaskCompleted _completedCallback;

///< summary>
///获取。设置允许主线程识别此任务的简单标识符。
///< / summary>
内部字符串TaskId
{
get {return _taskId; }
set {_taskId = value; }
}

///< summary>
/// Get,设置用于在完成时通知主线程的委托实例。
///< / summary>
内部SomeThreadTaskCompleted CompletedCallback
{
get {return _completedCallback; }
set {_completedCallback = value; }
}

///< summary>
///线程入口点函数。
///< / summary>
internal void ExecuteThreadTask()
{
//通常一个好主意告诉主线程是否有错误
bool isError = false;

//线程在这里开始执行。

//您将在这里开始某种长任务
//,如图像处理,文件解析,复杂查询等。

//线程执行完成后最终返回此功能。

//执行回调来告诉主线程这个任务是完成的。
_completedCallback.Invoke(_taskId,isError);


}

}
}


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. What is the meaning of a tread without a delegate
  2. If a delegate is necessary - then please tell me what and how the connection is made to the delegate.

解决方案

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.

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.

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.

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天全站免登陆