簡體   English   中英

線程安全事件-這是“干凈”的方式嗎? -2

[英]Thread-safe events - is this a “clean” way? - 2

假設此線程有建設性批評線程安全事件-這是“干凈”的方法嗎? 我坐下來,嘗試閱讀多線程的整個主題。

這是一些具有相同基本問題的代碼:這是使用事件創建非凍結UI的既定方法嗎?

public partial class Form1 : Form
{
    public delegate void MyThreadUpdateHandler(string s);

    public event MyThreadUpdateHandler MyThreadUpdate;
    System.Threading.Thread MyThread;


    public Form1()
    {
        InitializeComponent();
    }

    void DoTheCount()
    {
        int a = 0;

        while (a < int.MaxValue)
        {
            if (a % 1000000 == 0)
            {
                this.MyThreadUpdate(a.ToString());
            }

            a++;
        }
    }

    private void Form1_MyThreadUpdate(string s)
    {
        this.lblEvent.Invoke((MethodInvoker) delegate ()
        {
            lblEvent.Text = s;
        });
    }

    private void btnStartThread_Click(object sender, EventArgs e)
    {
        MyThreadUpdate += Form1_MyThreadUpdate;

        if (MyThread == null)
            MyThread = new System.Threading.Thread(new System.Threading.ThreadStart(DoTheCount));

        lblStatus.Text = "Starting thread";


        if (MyThread.ThreadState == System.Threading.ThreadState.Unstarted)
            MyThread.Start();

    }

    private void btnAbortThread_Click(object sender, EventArgs e)
    {
        MyThread.Abort();
    }
}

但是,有些事情我還是不明白。 為什么有些示例使用像這樣的Program()? http://www.codeproject.com/Articles/667298/Using-ThreadStaticAttribute

謝謝 :)

但是,有些事情我還是不明白。 為什么有些示例使用像這樣的Program()? http://www.codeproject.com/Articles/667298/Using-ThreadStaticAttribute

該代碼是

    static void Main(string[] args)
    {
        Program prog = new Program();

        //define the threads
        Thread thread1 = new Thread(new ThreadStart(prog.ThreadFunc1));
        Thread thread2 = new Thread(new ThreadStart(prog.ThreadFunc2));

這允許開發人員從靜態函數調用實例函數public void ThreadFunc1()public void ThreadFunc2() - static void Main(string[] args)

更新1

創建非凍結UI的既定方法是,在單獨的線程上進行所有耗時的活動,並封送對UI線程的調用, 僅對其進行更新。 您實現的內容遵循相同的想法。

我只想提一點,盡管這與凍結UI無關。

請使用ThreadPool而不是System.Threading.Thread

TaskBackgroundWorkerSystem.Threading.TimerAsynchronous Programming Model都使用ThreadPool 或者您也可以使用ThreadPool.QueueUserWorkItem

在非常特殊的情況下,應使用System.Threading.Thread而不是ThreadPool

首先,讓我說,我為您感到抱歉,嘗試使用舊式庫。

好的。 您符合我在.net中使用線程的少數幾個原因之一

長時間運行舊版庫

現在,閱讀您以前的代碼,我覺得您想將Rx.Net用於項目。

我將從為您的庫創建IObservable開始。

public static class LibraryHelper
{
    public static IObservable<EventPattern<StatusChangedEventArg>> StatusObservable(this ComLibrary com)
    {
        return Observable.FromEventPattern<EventHandler<StatusChangedEventArg>, StatusChangedEventArg>(x => com.FooEvent +=x, x => com.FooEvent -= x);
    }
}

這將允許您將Rx.Net與您的庫一起使用,就像這樣...

private async void btnStartThread_Click(object sender, EventArgs e)
{
    ComLibary com = new ComLibray();

    lblStatus.Text = "Starting thread";

    // using is there to unsubscribe after the call, to prevent a memory leak.
    var subscription = com.StatusObservable()
       //Magic sauce 
       //http://stackoverflow.com/questions/7417978/how-to-get-a-winform-synchronization-context-or-schedule-on-a-winform-thread
      .ObserveOn(SynchronizationContext.Current)
      .Subscribe(@event => {
         //Do something on the UI thread
      });
   using(subscription)
   {
           //Task.Run uses a background thread to get the data from your COM

          var result = await Task.Run(()=> com.Read());
           //back in UI thread. Do stuff.
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM