对不起,我的英语不好。希望有人建议我更好地解决我的问题。
我已经搜索过,但似乎找不到我的问题的答案。
目前,我正在编写一个 C# WPF 应用程序。这个应用程序将在很长一段时间内执行繁重的任务。所以我决定用那个繁重的方法创建另一个类,并将该方法传递给另一个线程。我必须创建一个类来做到这一点,因为繁重的方法需要参数。
我希望能够暂停和恢复该线程。我知道我应该使用ManualResetEvent
对象或Thread.Sleep
方法。
经过数小时的尝试和测试,我很困惑为什么我总是挂起 UI 线程但繁重的线程仍在运行。我试过的是:
在.
ManualResetEvent
_mre
_HeavyClass
当用户单击暂停按钮时,UI 类将调用该方法heavyClass.mre.WaitOne()
。class HeavyClass { // properties ManualResetEvent mre = new ManualResetEvent(false); public void HeavyRun() { //Do something takes really long time //And doesn't have any loops } } class MainWindow : Window { // properties private HeavyClass heavyClass = new HeavyClass(); private void buttonStart_Click(object sender, RoutedEventArgs e) { Thread t = new Thread(heavyClass.HeavyRun); t.Start(); } private void buttonPause_Click(object sender, RoutedEventArgs e) { heavyClass.mre.WaitOne(); } }
SleepThread
创建一个内部调用的方法HeavyClass
。当用户单击暂停按钮时,UI 类将调用该方法heavyClass.SleepThread()
。class HeavyClass { //properties ManualResetEvent mre = new ManualResetEvent(false); public void SleepThread() { Thread.Sleep(Timeout.Infinite); //mre.WaitOne(); //They are the same behavior } public void HeavyRun() { //Do something takes really long time //And doesn't have any loops } } class MainWindow : Window { // properties private HeavyClass heavyClass = new HeavyClass(); private void buttonStart_Click(object sender, RoutedEventArgs e) { Thread t = new Thread(heavyClass.HeavyRun); t.Start(); } private void buttonPause_Click(object sender, RoutedEventArgs e) { heavyClass.SleepThread(); } }
EventHandler<MainWindow> PauseThread
在 UI 类内部创建一个,然后在HeavyClass
. 当用户单击暂停按钮时,UI 类将触发事件PauseThread(this, this)
。class MainWindow : Window { // properties private HeavyClass heavyClass = new HeavyClass(); public event EventHandler<MainWindow> PauseThread; private void buttonStart_Click(object sender, RoutedEventArgs e) { Thread t = new Thread(heavyClass.HeavyRun); t.Start(); } private void buttonPause_Click(object sender, RoutedEventArgs e) { PauseThread(this, this); } } class HeavyClass { // properties ManualResetEvent mre = new ManualResetEvent(false); public void HeavyRun() { MainWindow.PauseThread += (s, E) => { Thread.Sleep(Timeout.Infinite); //mre.WaitOne(); //They are the same behavior }; //Do something takes really long time //And doesn't have any loops } }
正如我上面所说,我总是暂停 UI 线程,而繁重的任务仍在运行。
最后,我知道了我的问题的本质。即:哪个线程调用 Thread.Sleep() 或 WaitOne() 将被阻塞。是的,“哪个线程”,而不是“哪个类”。
现在一切对我来说都有意义。但这并不能帮助我实现目标。这让我认为我正在做看似不可能的事情。很明显,我想通过另一个线程暂停一个线程。但是另一个线程是调用任何类型的“挂起线程”的那个,所以它是被挂起的那个。我不知道如何使沉重的方法自行暂停。它正在运行,它怎么知道用户何时点击了暂停按钮?
我完全不知所措。有人请帮助我使我的应用程序按预期工作。
顺便说一句,这不可能的事情让我觉得我做错了,是吗?
更新:如果你喜欢看我的繁重任务,其实很简单
class HeavyClass
{
public string filePath = "D:\\Desktop\\bigfile.iso";//This file is about 10GB
public string HeavyRun()
{
string MD5Hash;
MD5 md5 = MD5.Create();
Stream stream = File.OpenRead(filePath);
MD5Hash = Encoding.Default.GetString(md5.ComputeHash(stream));
return MD5Hash;
}
}