gpt4 book ai didi

c# - 如何在不阻塞 UI 的情况下等待线程完成

转载 作者:可可西里 更新时间:2023-11-01 08:18:00 25 4
gpt4 key购买 nike

我希望我的程序在下行之后等待

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

如上方法是通过StartProcessWithProgress()方法在内部调用线程。我希望该线程在//code logic -2 行被执行之前完成。同时,它不应该停止由 frmProgressBar.UpdateProgress() 完成的 UI 更新。我该怎么做呢?

namespace NS1
{
public partial class frmMain : Form
{
private void button1_Click(object sender, EventArgs e)
{
frmProgressBar frmProgressBarObj = PullMSI.ExtractByMSIName("products.txt", false);
//code logic - 2
MessageBox.Show("This is executing immediately.
I want to wait until above thread is complete");
}
}

public partial class frmProgressBar : Form
{

public void UpdateProgress(String strTextToDisplayOnProgress)
{
progressBar1.BeginInvoke(
new Action(() =>
{
progressBar1.Value++;
lblFileName.Text = strTextToDisplayOnProgress;
if (progressBar1.Value == progressBar1.Maximum)
{
this.Hide();
}
}));
}

public delegate void DelProgress();

public void StartProcessWithProgress(DelProgress delMethodCode, int maxCount)
{
InitializeProgress(maxCount);
Thread backgroundThread = new Thread(new ThreadStart(delMethodCode));
backgroundThread.Start();
}
}

public static class PullMSI
{
public static frmProgressBar ExtractByMSIName(String strProductFilePath, bool reNameMSI)
{
frmProgressBar frmProgressBar = new frmProgressBar();

frmProgressBar.StartProcessWithProgress(() =>
{
//StreamRader sr declaration and other code

while (!sr.EndOfStream)
{
//logic here
frmProgressBar.UpdateProgress("Copying sr.msiname");
}
}, 2);

return frmProgressBar;
}
}
}

最佳答案

我很惊讶你以前没有使用过这些东西,但我真的建议你阅读 C# 中的线程,因为理解复杂性和学习语言从根本上很重要。

以下是您实现目标的三种不同方式:

<强>1。使用重置事件(进一步阅读:https://msdn.microsoft.com/en-us/library/system.threading.manualreseteventslim(v=vs.110).aspx)。如果您的 C# 版本没有 ManualResetEventSlim,请将其替换为 ManualResetEvent 并将 Wait() 更改为 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) 使用任务并行库 (TPL)。 进一步阅读: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) 使用异步/等待。延伸阅读: 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.");
}
}

同样值得一提的是: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)和 Interlocked(https://msdn.microsoft.com/en-us/library/system.threading.interlocked(v=vs.110).aspx)。

关于c# - 如何在不阻塞 UI 的情况下等待线程完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31160697/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com