How can I wait a method to finish or converting to Sync ?
My idea is that when I call CaptureImage()
the program will wait until the image is captured at bmp = new Bitmap(screenshot.ToBitmap());
in void Callback(IAsyncResult result)
The problem is that sometimes it's trying to process the image before it's captured and I'm getting a black screen as result
This is my code:
DateTime start;
private void CaptureImage()
{
start = DateTime.Now;
progressBar1.Maximum = 1;
progressBar1.Step = 1;
progressBar1.Value = 0;
DoRequest();
}
void DoRequest()
{
try
{
progressBar1.Invoke(new MethodInvoker(delegate ()
{
if (progressBar1.Value < progressBar1.Maximum)
{
progressBar1.PerformStep();
Size? resize = null;
_captureProcess.CaptureInterface.BeginGetScreenshot(new Rectangle(0, 0, 0, 0), new TimeSpan(0, 0, 2), Callback, resize, (ImageFormat)Enum.Parse(typeof(ImageFormat), "Bitmap"));
}
}));
}
catch
{
}
}
public IAsyncResult BeginGetScreenshot(Rectangle region, TimeSpan timeout, AsyncCallback callback = null, Size? resize = null, ImageFormat format = ImageFormat.Bitmap)
{
Func<Rectangle, TimeSpan, Size?, ImageFormat, Screenshot> getScreenshot = GetScreenshot;
return getScreenshot.BeginInvoke(region, timeout, resize, format, callback, getScreenshot);
}
void Callback(IAsyncResult result)
{
Screenshot screenshot;
try
{
screenshot = _captureProcess.CaptureInterface.EndGetScreenshot(result);
}
catch
{
screenshot = null;
}
if (screenshot != null)
{
using (screenshot)
try
{
_captureProcess.CaptureInterface.DisplayInGameText("Screenshot captured...");
if (screenshot != null && screenshot.Data != null)
{
bmp = new Bitmap(screenshot.ToBitmap());
}
Thread t = new Thread(new ThreadStart(DoRequest));
t.Start();
}
catch
{
}
while (!result.IsCompleted)
{
Thread.Sleep(200);
}
}
}
public Screenshot GetScreenshot(Rectangle region, TimeSpan timeout, Size? resize, ImageFormat format)
{
lock (_lock)
{
Screenshot result = null;
_requestId = Guid.NewGuid();
_wait.Reset();
SafeInvokeScreenshotRequested(new ScreenshotRequest(_requestId.Value, region)
{
Format = format,
Resize = resize,
});
_completeScreenshot = (sc) =>
{
try
{
Interlocked.Exchange(ref result, sc);
}
catch
{
}
_wait.Set();
};
_wait.WaitOne(timeout);
_completeScreenshot = null;
return result;
}
}
Please let me know if there's something missing or I can improve my question
Thank you
EDIT:
I've tested by changing the method public IAsyncResult BeginGetScreenshot
Instead of this:
Func<Rectangle, TimeSpan, Size?, ImageFormat, Screenshot> getScreenshot = GetScreenshot;
return getScreenshot.BeginInvoke(region, timeout, resize, format, callback, getScreenshot);
Testing with this:
Func<Rectangle, TimeSpan, Size?, ImageFormat, Screenshot> getScreenshot = GetScreenshot;
IAsyncResult result = getScreenshot.BeginInvoke(region, timeout, resize, format, callback, getScreenshot);
while (!result.IsCompleted)
{
Thread.Sleep(100);
}
getScreenshot.EndInvoke(result);
return result;
But I got System.InvalidOperationException: 'You can only call EndInvoke once for each asynchronous operation.'