Задача возвращает «поток вызовов не может получить доступ к этому объекту» - PullRequest
0 голосов
/ 12 февраля 2020

Я хочу создать массив со всеми плагинами, установленными на потоковых ссылках, а затем сравнить его с заданной строкой, чтобы проверить, есть ли в приложении вспомогательный плагин для данного сайта. Я не хочу замораживать приложение для этого, поэтому какое-то время l oop внутри метода syn c мне не подходит, поэтому я попытался сделать это с помощью Tasks.

Это код моего приложения:

private void SupportCheckButton_Click(object sender, RoutedEventArgs e)
{
    Task<bool> task = Task.Run(async () => await Methods.isSiteSupported(LinkText.Text));

    task.Wait();
    if (task.Result)
    {
        cmdOutputLabel.AppendText(new Uri(Methods.FormatedUrl(LinkText.Text)).Host + " is supported.");
    }
    else
    {
        cmdOutputLabel.AppendText(new Uri(Methods.FormatedUrl(LinkText.Text)).Host + " is not supported. Yet...");
    }
}

Это код для моего library:

private static void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    if(!string.IsNullOrWhiteSpace(e.Data))
        plugins = e.Data.Split(',');
}

public static async Task<bool> isSiteSupported(string site)
{
    try
    {
        site = FormatedUrl(site);
        if (GetUrlResponse(site))
        {
            string siteDomain = new Uri(site).Host;
            string[] siteDivided = siteDomain.Split('.');

            if (siteDivided.Length == 2)
                siteDomain = siteDivided[0];
            else if (siteDivided.Length >= 2)
            {
                siteDomain = string.Empty;
                for (int i = 0; i < siteDivided.Length - 1; i++)
                {
                    siteDomain += siteDivided[i];
                }
            }

            Process proc = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "CMD.exe",
                    Arguments = "/C streamlink --plugins",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true
                }
            };
            proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
            proc.Start();
            proc.BeginOutputReadLine();
            if (plugins == null)
            {
                await GetPluginList();
            }
            return plugins.Contains(siteDomain);
        }
        else
        {
            return false;
        }
    }
    catch
    {
        return false;
    }
}

public static async Task<string> GetPluginList()
{
    await Task.Run(() => {
        while (plugins == null)
        {
            System.Threading.Thread.Sleep(500);
        }
        if (plugins.Length > 0)
        {
            if (plugins[0].Contains("Loaded plugins: "))
                plugins[0] = plugins[0].Remove(plugins[0].IndexOf("Loaded plugins: "), 10);
            for (int i = 0; i < plugins.Length; i++)
            {
                plugins[i] = plugins[i].Trim();
            }
        }
    });
    return null;
}

Но после многих попыток я не смог сделать это правильно. Прямо сейчас, с этим точным кодом, он возвращает InvalidOperationException о том, что Поток вызовов не может получить доступ к объекту Task.Wait();, потому что он используется в другом Потоке. Во всяком случае, я не вижу, какой другой поток использует его.

...