0

I am doing c # form application. The application is basically a video converter implementation. I have two buttons called convert and conver the stop. Here's what I want to do; I don't want the form to lock itself, even if I click on any of these. I may cancel the process or close the form at that time. I need to do async, but I don't know how. I can't use a backgroundworker because I'm basically dealing with big data. He can lock the form more. Please help.

convert the stop code;

private void Button7_Click(object sender, EventArgs e)
    {
        var ffmpeg = new NReco.VideoConverter.FFMpegConverter();
        ffmpeg.Stop();
                MessageBox.Show("convert is stopped");
    }
Zeynep Baran
  • 37
  • 1
  • 7
  • 1
    `await Task.Run(() => { /* Put your CPU-bound code here */ });`. Don't forget to add the `async` modifer to your event handler though (i.e., `private async void Button7_Click(...)`. – 41686d6564 stands w. Palestine Oct 28 '19 at 07:42
  • BackgroundWorker will not lock a form, you can use it. – Fabio Oct 28 '19 at 07:42
  • 1
    You should read the MS article on non ui blocking operations [here](https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/keep-the-ui-thread-responsive) and the answer to a similar question [here](https://stackoverflow.com/questions/48681248/why-is-the-windows-forms-ui-blocked-when-executing-task-with-continuewith) – RedFox Oct 28 '19 at 07:43
  • where exactly will this code be? Is the form in load, or when you double-click the button? @ahmed abdelhameed – Zeynep Baran Oct 28 '19 at 07:43
  • But ı cant use,When the form finishes, the backgroundworker is running behind when I make a second operation before the form closes. whereas I shut it down as soon as the process is over. @fabio – Zeynep Baran Oct 28 '19 at 07:45
  • You need to make ffmpeg a field to your form class. Then you can use the FormClosing event to call Stop on it, as well as in the Button_Click event. As is, you are calling stop on a newly created converter, which is not the one you started. – Fildor Oct 28 '19 at 07:51
  • ı have a error like this. I make async all the button event. And then give me like this error. Textbox2 I'm replacing the last saved file here"System.InvalidOperationException: 'Cross-thread operation not valid: Control 'textBox2' accessed from a thread other than the thread it was created on.'" – Zeynep Baran Oct 28 '19 at 08:01
  • Please add the respective code, where you get the error. Mark the line, where it happens. – Fildor Oct 28 '19 at 08:03
  • 1
    It looks like the [FFMpegConverter class](https://www.nrecosite.com/doc/NReco.VideoConverter/html/T_NReco_VideoConverter_FFMpegConverter.htm) exposes methods that start and stop a background process. So you don't need to spin up a thread of your own. I think you just need to keep a reference to your object as a form field rather than a local variable. – John Wu Oct 28 '19 at 08:03

1 Answers1

3

Like this:

private async void Button7_Click(object sender, EventArgs e)
{
    await Task.Run(() => 
    {
        //code here that takes a long time. NB nothing that must be run on the main thread
        var ffmpeg = new NReco.VideoConverter.FFMpegConverter();
        ffmpeg.Stop();
    });
    //when the above task completes this will then be called on the original thread context (i.e. the main ui thread)
    MessageBox.Show("convert is stopped");
}

Note that the MessageBox.Show will be called after the task has completed but the control will return to the main thread at the await call. This is what confuses people new to async.

Also note that ordinarily an async function will have a Task or Task<T> return type, but as this is an event handler it has void return type. It is one of the few cases where a void return type is correct for an async function.

Tim Rutter
  • 4,549
  • 3
  • 23
  • 47
  • do I have to async other events? – Zeynep Baran Oct 28 '19 at 08:06
  • @ZeynepBaran Async is _not_ your problem. See my and John Wu's comments on your question. – Fildor Oct 28 '19 at 08:07
  • @Fildor I think you're right! I did think a Stop function would not really need to be run asynchronously – Tim Rutter Oct 28 '19 at 08:08
  • no I am just telling you what ı do. I dont have any error converter. My problem is one button in the form is active, I can't use the other – Zeynep Baran Oct 28 '19 at 08:10
  • @ZeynepBaran And you don't give enough context in the question, to analyze what the problem actually is. You are assuming you have problem X, while some users here (including me) suspect you are having problem Y. – Fildor Oct 28 '19 at 08:13
  • I am telling you, you do not encounter any error problem warning about converter stop process. I'm just saying that when one of the buttons is active, I can't use the other buttons, and the form is locked until the process is finished. Converter is just the work that my form has done. I just mentioned what the form did. – Zeynep Baran Oct 28 '19 at 08:17
  • @timrutter, how can ı used it? One button is working but the other button is inactive? I write this code, but am ı write other code in form? – Zeynep Baran Oct 28 '19 at 08:59
  • @Zeynap Baran not sure. you asked how to do async so I showed that. You'd have to post your code to be able to say any more. – Tim Rutter Oct 28 '19 at 12:49
  • Hello @Tim, I just wrote void function with some long task to do, I'm just curious if its correct because there is no parameters etc like this -> private async void Functionx(), and I'm calling it later on with a button – Kuba Do Oct 28 '19 at 14:37
  • 1
    @Kuba https://stackoverflow.com/questions/12144077/async-await-when-to-return-a-task-vs-void – Tim Rutter Oct 28 '19 at 14:58