How to wait for thread to complete without blocking UI

后端 未结 2 898
-上瘾入骨i
-上瘾入骨i 2020-12-05 03:44

I want my program to wait after below line

frmProgressBarObj = PullMSI.ExtractByMSIName(\"products.txt\", false);

as above method is intern

相关标签:
2条回答
  • 2020-12-05 04:01

    If you're using .NET 4.0 (with VS2012) or above, you can do this quite easily with the Task Parallel Library and async-await:

    private async void button1_Click(object sender, EventArgs e)
    {
        frmProgressBar frmProgressBarObj = await Task.Run(() =>
                          PullMSI.ExtractByMSIName("products.txt", false));
    
        MessageBox.Show(string.Format("Returned {0}", frmProgressBarObj.ToString());
    }
    

    For .NET 4, you'll need to add Microsoft.Bcl.Async.

    0 讨论(0)
  • 2020-12-05 04:18

    I'm very surprised you haven't worked with any of these before but I would really recommend reading about threading in C# since it's fundamentally important to understand the intricacies and learning the language.

    Below are three different ways you can achieve what you want:

    1. Using reset events (further reading: https://msdn.microsoft.com/en-us/library/system.threading.manualreseteventslim(v=vs.110).aspx). If your C# version doesn't have the ManualResetEventSlim, replace it with ManualResetEvent and change Wait() with WaitOne()

    class LockingWithResetEvents
    {
        private readonly ManualResetEvent _resetEvent = new ManualResetEvent(false);
    
        public void Test()
        {
            MethodUsingResetEvents();
        }
    
        private void MethodUsingResetEvents()
        {
            ThreadPool.QueueUserWorkItem(_ => DoSomethingLong());
            ThreadPool.QueueUserWorkItem(_ => ShowMessageBox());
        }
    
        private void DoSomethingLong()
        {
            Console.WriteLine("Doing somthing.");
            Thread.Sleep(1000);
            _resetEvent.Set();
        }
    
        private void ShowMessageBox()
        {
            _resetEvent.WaitOne();
            Console.WriteLine("Hello world.");
        }
    }
    

    2) Using Task Parallel Library (TPL). Further reading: https://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx

    class LockingWithTPL
    {
        public void Test()
        {
            Task.Factory.StartNew(DoSomethingLong).ContinueWith(result => ShowMessageBox());
        }
    
        private void DoSomethingLong()
        {
            Console.WriteLine("Doing somthing.");
            Thread.Sleep(1000);
        }
    
        private void ShowMessageBox()
        {
            Console.WriteLine("Hello world.");
        }
    }
    

    3) Using Async/Await. Further reading: https://msdn.microsoft.com/en-us/library/hh191443.aspx

    class LockingWithAwait
    {
        public void Test()
        {
            DoSomething();
        }
    
        private async void DoSomething()
        {
            await Task.Run(() => DoSomethingLong());
            ShowMessageBox();
        }
    
        private async void DoSomethingLong()
        {
            Console.WriteLine("Doing somthing.");
            Thread.Sleep(10000);
        }
    
        private void ShowMessageBox()
        {
            Console.WriteLine("Hello world.");
        }
    }
    

    Also good to know: Mutex (https://msdn.microsoft.com/en-us/library/system.threading.mutex(v=vs.110).aspx), Semaphore (https://msdn.microsoft.com/en-us/library/system.threading.semaphore(v=vs.110).aspx), Lock (https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx), SemaphoreSlim (https://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx), Monitor (https://msdn.microsoft.com/en-us/library/system.threading.monitor(v=vs.110).aspx) and Interlocked (https://msdn.microsoft.com/en-us/library/system.threading.interlocked(v=vs.110).aspx).

    0 讨论(0)
提交回复
热议问题