Здравствуйте. В терминологии VS не очень разбираюсь. По-этому поправьте, если что-то не так назову. Использую Microsoft visual studio community 2019 и проект WindowsFormsApp. Нужно создать массив из фреймов и разместить их плиткой на форме. В каждом фрейме нужно запустить на выполнение цикл в потоке, чтобы программа не вешалась. Если я правильно понял, то фрейм это объект класса UserControl. Чтобы его добавить, нажимаю в меню Project -> Add user control и накидываю на него компоненты: Button, ProgressBar, Label. По нажатию кнопки, в каждом таком фрейме создается поток и запускается цикл. Проблема в том, что если запустить более одного потока с циклом, то форма намертво вешается до тех пор, пока одновременно работают два и более потока. Вернее, более двух потоков запустить вообще невозможно по причине зависания главной формы. А при двух активных потоках обновляются только прогрессбары, а всё остальное висит. Почему так происходит? Form1.cs:
| Код | using System; using System.Threading; using System.Windows.Forms;
namespace test_thread { public partial class Form1 : Form { SynchronizationContext fContext = null; MyFrame[] frames = new MyFrame[0]; public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) { fContext = SynchronizationContext.Current; for (int i = 0; i < 4; i++) { Array.Resize(ref frames, frames.Length + 1); frames[i] = new MyFrame(fContext); frames[i].Parent = sender as Form; frames[i].Left = 0; frames[i].Top = i * frames[i].Height; } Form1_Resize(sender, e); }
private void Form1_Resize(object sender, EventArgs e) { for (int i = 0; i < frames.Length; i++) { frames[i].Width = Width; frames[i].DoResize(); } } } }
|
MyFrame.cs:
| Код | using System; using System.Threading; using System.Windows.Forms;
namespace test_thread { public partial class MyFrame : UserControl { public SynchronizationContext fContext = null; int c = 0; int max = 25000; public MyFrame(object par) { fContext = (SynchronizationContext)par; InitializeComponent(); }
public void DoResize() { progressBar1.Left = 0; progressBar1.Width = Width - 30; }
private void BtnStart_Click(object sender, EventArgs e) { c++; btnStart.Text = Convert.ToString(c); btnStart.Enabled = false; MyThread1 myThr = new MyThread1(); myThr.max = max; myThr.UpdateIndicators += Thread_UpdateIndicators; myThr.WorkCompleted += Thread_Complete; Thread thr = new Thread(myThr.Work); thr.Start(fContext); }
private void MyFrame_Load(object sender, EventArgs e) { progressBar1.Maximum = max; label1.Text = "0 / " + Convert.ToString(max); }
public void Thread_UpdateIndicators(int progress) { progressBar1.Value = progress; label1.Text = Convert.ToString(progress) + " / " + Convert.ToString(max); }
public void Thread_Complete(bool canceled) { btnStart.Enabled = true; }
} }
|
MyThread1.cs:
| Код | using System; using System.Threading;
namespace test_thread { public class MyThread1 { private bool fCanceled = false; public int max = 10; public void Work(object param) { SynchronizationContext context = (SynchronizationContext)param; for (int i = 0; i <= max; i++) { if (fCanceled) break; context.Send(OnUpdate, i); } context.Send(OnCompleted, fCanceled); }
public void Cancel() { fCanceled = true; } public void OnUpdate(object i) { if (UpdateIndicators != null) UpdateIndicators((int)i); }
public void OnCompleted(object canceled) { if (WorkCompleted != null) WorkCompleted((bool)canceled); } public event Action<int> UpdateIndicators; public event Action<bool> WorkCompleted; } }
|
|