C# 异步方法SpiDevice.FromIdAsync未完成

C# 异步方法SpiDevice.FromIdAsync未完成,c#,raspberry-pi3,spi,windows-10-iot-core,C#,Raspberry Pi3,Spi,Windows 10 Iot Core,我正在尝试通过SPI建立一个简单的连接,但是当尝试获取SpiDevice时,SpiDevice.FromIdAsync方法永远不会完成。这种情况几乎总是发生,少数例外情况似乎是随机的 spi = await SpiDevice.FromIdAsync(dis[0].Id, settings); 用于设置连接的代码来自 在本例中,我将一个字节输出到作为移位寄存器工作的LED驱动器。我使用Raspberry Pi 3作为目标设备,Visual Studio Community 2017作为我的ID

我正在尝试通过SPI建立一个简单的连接,但是当尝试获取SpiDevice时,SpiDevice.FromIdAsync方法永远不会完成。这种情况几乎总是发生,少数例外情况似乎是随机的

spi = await SpiDevice.FromIdAsync(dis[0].Id, settings);
用于设置连接的代码来自

在本例中,我将一个字节输出到作为移位寄存器工作的LED驱动器。我使用Raspberry Pi 3作为目标设备,Visual Studio Community 2017作为我的IDE

MainPage.xaml.cs

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Devices.Gpio;
using Windows.Devices.Spi;
using Windows.Devices.Enumeration;
using System.Threading.Tasks;

namespace SPI_Test
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            try
            {
                InitGPIO();
                InitSpi().Wait();

                timer = new DispatcherTimer();
                timer.Interval = TimeSpan.FromMilliseconds(500);
                timer.Tick += Timer_Tick;
            }
            catch (Exception)
            {

            }
        }

        GpioPin enablePin;
        SpiDevice spi;

        private void InitGPIO()
        {
            var gpio = GpioController.GetDefault();

            //create pin to control the output of the LED driver
            //the outputs are active when the pin is low
            enablePin = gpio.OpenPin(12);
            enablePin.Write(GpioPinValue.High); //disable outputs at first
            enablePin.SetDriveMode(GpioPinDriveMode.Output);
        }

        private async Task InitSpi()
        {
            try
            {
                // Use chip select line CS0
                var settings = new SpiConnectionSettings(0);
                // Set clock to 10MHz 
                settings.ClockFrequency = 10000000;

                // Get a selector string that will return our wanted SPI controller
                string aqs = SpiDevice.GetDeviceSelector("SPI0");

                // Find the SPI bus controller devices with our selector string
                var dis = await DeviceInformation.FindAllAsync(aqs);

                spi = await SpiDevice.FromIdAsync(dis[0].Id, settings);  /* Create an SpiDevice with our bus controller and SPI settings */

            }
            /* If initialization fails, display the exception and stop running */
            catch (Exception ex)
            {
                throw new Exception("SPI Initialization Failed", ex);
            }
        }

        private DispatcherTimer timer;
        private byte value = 0;
        private void Timer_Tick(object sender, object e)
        {
            enablePin.Write(GpioPinValue.High); //disable outputs
            spi.Write(new byte[] { value++ }); //send the current value to the LEDs and increase by 1
            enablePin.Write(GpioPinValue.Low); //re-enable outputs
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            timer.Start();
        }
    }
}
MainPage.xaml

<Page
    x:Class="SPI_Test.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SPI_Test"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <Button Click="Button_Click" Content="Start" Margin="15" />
        </StackPanel>
    </Grid>
</Page>

由于阻塞调用
.Wait()
和异步调用的混合,您遇到了死锁。我建议将该逻辑转移到事件处理程序。像加载的
一样

public MainPage() {
    this.InitializeComponent();
    this.Loaded += async (sender, e) => {
        try {
            InitGPIO();
            await InitSpi();

            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(500);
            timer.Tick += Timer_Tick;
        } catch (Exception) {

        }
    };
}

谢谢你的回答。它现在起作用了。我从来没有听说过死锁。我找到了这篇文章,它帮助我理解了这个问题。