نمایش Loader حین پردازش سنگین در WPF سی شارپ
موضوع : نمایش یک Loader همزمان با اجرای یک پردازش سنگین
چیزی که میخوام انجام بدم : بعد از کلیک روی یک دکمه در داخل این رویداد
1- یک لودر (یک گیف یا انیمیشن) نشان دهم (Visible)
2- عملیات سنگین هم شروع به کار کند
3- در پایان عملیات سنگین لودر هم مخفی شود
کاری که انجام دادم :
private void Button1_Click(object sender, RoutedEventArgs e)
{
Spinner.Visibility = Visibility.Visible;
Task.Run(() =>
{
//Simulation Long Process
var TheRsult = dbms.Database.SqlQuery<object>("WAITFOR DELAY '00:00:03' SELECT GETDATE()").FirstOrDefault();
//Thread.Sleep(500);
for (int i = 0; i < 1000; i++)
{
Console.Write(i);
}
MessageBox.Show("Finished", "Information", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.Yes);
Dispatcher.Invoke(() =>
{
Spinner.Visibility = Visibility.Collapsed;
});
});
}
مشکل چیه ؟
- زمانی که عملیات داخل رویداد کلیک در حال پردازش است پنجره شما (برنامه در حال اجرا) به حالت قفل و فریز شده میرود و نمیتوان با آن هیچ کاری انجام داد , تا پایان پردازش
پس من سعی کردم که دستور نمایش لودر رو داخل یک Task (Thread) بذارم به این شکل :
//still Ui will frezz after pressing the button !
Dispatcher.Invoke(() =>
{
Spinner.Visibility = Visibility.Visible;
});
اما باز هم یو آی (UI) قفل مشید !
من نمیخوام عملیات اصلی رو داخل یک تِرِد بذارم (عملیات سنگین) میخوام به یه شکلی بتونم لودر خودم رو موقع پردازش سنگین به شکلی که برنامه قفل و فریز نشه نشان بدم .
یک فانکشن DoEvents هم هست که ظاهرا استفاده از اون کار صحیحی نیست و درضمن کار هم نکرد ! ☻:
public void DoEventsWPFY()
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background,
new Action(delegate { }));
}
public void DoEventsWPFY2()
{
var frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(
delegate (object f)
{
((DispatcherFrame)f).Continue = false;
return null;
}), frame);
Dispatcher.PushFrame(frame);
}
public void DoEventsWPFY3()
{
var minFrameDelay = Observable.Interval(TimeSpan.FromMilliseconds(50)).Take(1).Replay();
minFrameDelay.Connect();
// synchronously add a low-priority no-op to the Dispatcher's queue
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => minFrameDelay.Wait()));
}
//یا ریفرنس ویندوز فرم رو به پروژه تون اضافه کنید و اینطوری صداش کنید :
System.Windows.Forms.Application.DoEvents();
// DoEvents();
// Your Code ...
//DoEvents();
سورس کامل : Full Source Code
منابع :
- https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/keep-the-ui-thread-responsive
- https://stackoverflow.com/questions/24804136/how-do-i-stop-my-ui-thread-from-locking-up
چه کاری باید انجام بدم ؟
لطفا راهنمایی بفرمایید
باتشکر از همگی
- آموزش استفاده از SignalR در Asp.net Core با مثال عملی
- ادغام چند گزارش استیمول سافت بصورت پی دی اف در یک فایل
- نحوه تغییر استایل کامپوننت select2 چگونه است ؟
- چگونه امنیت پروژه را در Asp.net Core افزایش دهیم ؟
- ارسال پارامتر در دستور window.open جی کویری
- ارسال پارامتر از طریق جاوااسکریپت با کلیک روی تگ a
- خطای 500 زمان اجرا شدن پروژه روی هاست
- کویری نویسی در استیمول سافت جهت فیلتر اطلاعات
- نمایش صفحه در پنجره جدید با کلیک روی لینک (تگ a) در Asp
- افزودن مقادیر به صورت دستی به List دریافت شده از ریپازیتوری
- مشکل تاریخ شمسی در سی شارپ
- نمایش گزارش stimulsoft روی کلاینت
- حذف کامل یک رکورد در جدول ریلیشن شده
- تفاوت های سی شارپ 8 با نسخه های قبلی چیه؟
- انتخاب چند سطر دلخواه توسط چک باکس در DataGrid و محاسبه جمع سطرهای انتخاب شده
- مقایسه ساختار دو دیتابیس در Sql Server
- اشکال در ایجاد کلید خارجی در Sql Server
- نمایش نوتیفکیشن در سی شارپ
- ارسال پارامتر از سی شارپ به استیمول سافت
- عدم نمایش عکس در دیتاگرید ویو در wpf