0

I'm implementing a Client who can ask a service for a certain action and also an abort button for this action. Once I run the action using background thread the abort button should become active, but instead the entire GUI is stuck with the mouse icon as hour glass (Should mention that the action is still indeed occurring).

    private void actionButton_Click(object sender, EventArgs e)
    {
        Run(RunMode.Action);
    }

    private void Run(RunMode runMode)
    {
        abortButton.Enabled = true;
        try
        {
            var name = "ds_file";
            var url = UrlProvider.BuildRequestUrl(runMode, name);

            StartLoading($"Running request: {url}");

            RunWorker(url);
        }
        catch (Exception ex)
        {
            AddToLog(ex.ToString());
            PopError("Failed to run, see error in log box");
        }

    }

    private void RunWorker(string url)
    {
        var worker = new BackgroundWorker();
        worker.DoWork += (sender, args) =>
        {
            DatabaseHelper.DisableAllJobs();
            HttpRequestsHandler.HttpGet(url);
            DatabaseHelper.EnableRegularJobs();
        };
        worker.RunWorkerCompleted += (sender, args) =>
        {
            StopLoading();
            abortButton.Enabled = false;
            if (args.Error != null)
            {
                PopError("Failed to run, see error in log box");
                AddToLog(args.Error.ToString());
            }
            else
            {
                PopInfo("Completed successfully");
            }
        };
        worker.RunWorkerAsync();
    }

What am I doing wrong?

Thanks

O. San
  • 1,107
  • 3
  • 11
  • 25
  • Read up on this Q: http://stackoverflow.com/questions/31160697/how-to-wait-for-thread-to-complete-without-blocking-ui – NotTelling Mar 20 '17 at 07:44
  • 1
    At a guess, some of the code you've not shown us has an `Invoke` that forces everything back onto the UI thread. Impossible to tell from the shown code but that's the usual mistake in this kind of scenario. – Damien_The_Unbeliever Mar 20 '17 at 07:46
  • 1
    Could you show us your Helper classes whose methods get called in the DoWork scope? – bl4y. Mar 20 '17 at 08:05
  • 2
    Maybe try to change background worker to async/await – daniell89 Mar 20 '17 at 08:22
  • 1
    does StartLoading is time consum method which take long time to finish? you can step into button click code execution to see where it stucks. – jay liu Mar 20 '17 at 08:34

2 Answers2

2

Following example run background service every 10 seconds to update GUI. You can modify it as you wish. By running your thread as async task your GUI never get hang.

public frm_testform()
    {

        InitializeComponent();

        dispatcherTimer_Tick().DoNotAwait();

    }

private async Task dispatcherTimer_Tick()
    {
        DispatcherTimer timer = new DispatcherTimer();
        TaskCompletionSource<bool> tcs = null;
        EventHandler tickHandler = (s, e) => tcs.TrySetResult(true);

        timer.Interval = TimeSpan.FromSeconds(10);
        timer.Tick += tickHandler;
        timer.Start();

        while (true)
        {
            tcs = new TaskCompletionSource<bool>();

            await Task.Run(() =>
            {
           // Run your background service and UI update here
            await tcs.Task;
        }

    }
0

It indeed turns out I had controls.enable = false in some part of the code (I really thought it totally meant for something else), thank you all for your help!!

O. San
  • 1,107
  • 3
  • 11
  • 25