首页 > 解决方案 > 任务返回“调用线程无法访问此对象”

问题描述

我想创建一个包含流链接上安装的所有插件的数组,然后将其与给定字符串进行比较,以检查应用程序是否具有给定站点的支持插件。我不想为此冻结应用程序,因此同步方法中的 while 循环不适合我,因此我尝试使用 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();对象,因为它正在另一个线程中使用。无论如何,我看不到其他线程正在使用它。

标签: c#multithreadingasynchronousexceptiontask

解决方案


推荐阅读