>  기사  >  백엔드 개발  >  C# WinForm 멀티스레드 개발 (2) ThreadPool 및 Timer

C# WinForm 멀티스레드 개발 (2) ThreadPool 및 Timer

黄舟
黄舟원래의
2017-02-20 10:54:151465검색

원본주소 : 링크를 열려면 클릭하세요

[Abstract]본 글에서는 C#을 소개합니다. WinForm 다중 스레드 개발을 위한 ThreadPool 및 Timer와 자세한 샘플 코드가 참조용으로 제공됩니다.

이 기사는 위에서 이어지며 스레드 풀과 타이머에 다시 초점을 맞춰 WinForm의 멀티스레딩 문제를 계속 논의합니다.

1. ThreadPool

스레드 풀(ThreadPool)은 여러 스레드가 필요한 짧은 작업(예: 자주 차단되는 작업)에 적합합니다. 단점은 생성된 스레드를 제어할 수 없고 우선순위를 설정할 수도 없다는 것입니다. 각 프로세스에는 단 하나의 스레드 풀만 있고 각 애플리케이션 도메인에는 단 하나의 스레드 풀(라인)만 있으므로 ThreadPool 클래스의 멤버 함수는 모두 정적임을 알 수 있습니다! ThreadPool.QueueUserWorkItem, ThreadPool.RegisterWaitForSingleObject 등을 처음 호출하면 스레드 풀 인스턴스가 생성됩니다. 스레드 풀의 두 가지 기능을 소개하겠습니다.


public static bool QueueUserWorkItem( //调用成功则返回true 
	    WaitCallback callBack,//要创建的线程调用的委托 
	    object state //传递给委托的参数 
	    )//它的另一个重载函数类似,只是委托不带参数而已

이 함수의 기능은 스레드 풀에 생성될 스레드를 대기열에 추가하는 것입니다. 스레드 풀 사용 가능한 스레드 수가 0이 아닌 경우(스레드 풀에는 생성된 스레드 수에 제한이 있고 누락된 값은 25임) 이 스레드가 생성되고 그렇지 않으면 스레드 풀에 대기하게 됩니다. 사용 가능한 스레드가 있을 때까지 기다리십시오.

public static RegisteredWaitHandle RegisterWaitForSingleObject( 
    WaitHandle waitObject,// 要注册的 WaitHandle 
    WaitOrTimerCallback callBack,// 线程调用的委托 
    object state,//传递给委托的参数 
    int TimeOut,//超时,单位为毫秒, 
    bool executeOnlyOnce //是否只执行一次 
); 
public delegate void WaitOrTimerCallback( 
    object state,//也即传递给委托的参数 
    bool timedOut//true表示由于超时调用,反之则因为waitObject 
);


이 함수의 기능은 한 번 생성되는 대기 스레드를 생성하는 것입니다. 이 함수는 waitObject 매개변수가 종료된 상태로 변경되거나 TimeOut이 설정된 시간에 도달할 때까지 "차단된" 상태에 있습니다. 이 "차단된" 상태는 스레드의 WaitSleepJoin 상태와 매우 다르다는 점에 주목할 가치가 있습니다. 스레드가 WaitSleepJoin 상태에 있으면 CPU는 스레드를 정기적으로 깨워 상태 정보를 폴링하고 업데이트한 다음 다시 WaitSleepJoin 상태로 들어갑니다. 스레드 전환은 리소스를 많이 사용하지만 이 함수로 생성된 스레드는 다릅니다. 실행을 트리거하기 전에 CPU는 이 스레드로 전환하지 않으며 CPU 시간을 차지하지도 않고 스레드 전환 시간도 낭비하지 않습니다. 하지만 CPU는 언제 실행할지 어떻게 알 수 있습니까? 실제로 스레드 풀은 이러한 트리거 조건을 모니터링하기 위해 일부 보조 스레드를 생성하며, 조건이 충족되면 해당 스레드도 시작됩니다. 물론 이러한 보조 스레드 자체도 시간이 걸리지만 더 많은 대기 시간을 생성해야 하는 경우 스레드를 사용하려면 스레드 풀의 장점이 더욱 분명해집니다.

자세한 데모:

namespace TestMethodInvoker
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            //ThreadPool.RegisterWaitForSingleObject(
            //    ev,
            //    new WaitOrTimerCallback(WaitThreadFunc),
            //    4,
            //    2000,
            //    false//表示每次完成等待操作后都重置计时器,直到注销等待 
            //    );
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunc), "test1");
            //Thread.Sleep(10000);
        }
        private delegate void MyInvokeDelegate(string name);
        private void Test(object o)
        {
            richTextBox1.Text += string.Format("the object is {0} \n", o);
        }
        public  void ThreadFunc(object b)
        {
            this.Invoke(new MyInvokeDelegate(Test), b);
        }
        public void WaitThreadFunc(object b, bool t)
        {
            richTextBox1.Text += string.Format("the object is {0},t is {1}\n", b, t);
        } 
    }
}

여기서 호출은 실제로 액션 및 func와 같은 다른 방법을 사용합니다. 예시 코드는 다음과 같습니다.

this.Invoke(new Action<string>(this.ChangeText), o.ToString());
this.Invoke(new Action(delegate() { this.textBox1.Text = o.ToString();}));
private void DoSomething(object o) 
{
    System.Func<string, int> f = new Func<string, int>(this.GetId);
    object result = this.Invoke(f, o.ToString());
    MessageBox.Show(result.ToString());
}
private int GetId(string name) 
{
    this.textBox1.Text = name;
    if (name == "Y") 
    {
       return 999;
    }
    else 
    {
        return 0;
    }
}

二、 Timer


它适用于需周期性调用的方法,它不在创建计时器的线程中运行,它在由系统自动分配的单独线程中运行。这和Win32中的SetTimer方法类似。它的构造为:

public Timer( 
    TimerCallback callback,//所需调用的方法 
    object state,//传递给callback的参数 
    int dueTime,//多久后开始调用callback 
    int period//调用此方法的时间间隔 
);//

如果 dueTime 为0,则 callback 立即执行它的首次调用。如果 dueTime 为 Infinite,则 callback 不调用它的方法。计时器被禁用,但使用 Change 方法可以重新启用它。如果 period 为0或 Infinite,并且 dueTime 不为 Infinite,则 callback 调用它的方法一次。计时器的定期行为被禁用,但使用 Change 方法可以重新启用它。如果 period 为零 (0) 或 Infinite,并且 dueTime 不为 Infinite,则 callback 调用它的方法一次。计时器的定期行为被禁用,但使用 Change 方法可以重新启用它。 

在创建计时器之后若想改变它的period和dueTime,我们可以通过调用Timer的Change方法来改变:

public bool Change( 
    int dueTime, 
    int period 
);//

    显然所改变的两个参数对应于Timer中的两参数。


 以上就是C# WinForm多线程开发(二) ThreadPool 与 Timer的内容,更多相关内容请关注PHP中文网(www.php.cn)!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.