Как я могу дождаться, пока метод завершится sh или преобразуется в Syn c? - PullRequest
0 голосов
/ 31 марта 2020

Как я могу дождаться, пока метод завершится sh или преобразуется в Syn c?

Моя идея заключается в том, что когда я вызываю CaptureImage(), программа будет ждать, пока изображение не будет записано в bmp = new Bitmap(screenshot.ToBitmap()); in void Callback(IAsyncResult result)

Проблема в том, что иногда он пытается обработать изображение до его захвата, и в результате я получаю черный экран

Это мой код:

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;
    }
}

Пожалуйста, дайте мне знать, если чего-то не хватает, или я могу улучшить свой вопрос

Спасибо

РЕДАКТИРОВАТЬ:

Я проверено путем изменения метода public IAsyncResult BeginGetScreenshot

Вместо этого:

Func<Rectangle, TimeSpan, Size?, ImageFormat, Screenshot> getScreenshot = GetScreenshot;

return getScreenshot.BeginInvoke(region, timeout, resize, format, callback, getScreenshot);

Тестирование с этим:

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;

Но я получил System.InvalidOperationException: 'You can only call EndInvoke once for each asynchronous operation.'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...