Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在WaitAsync完成之前处理连接?_C#_Async Await_Dbus_Manualresetevent_Freedesktop.org - Fatal编程技术网

C# 为什么在WaitAsync完成之前处理连接?

C# 为什么在WaitAsync完成之前处理连接?,c#,async-await,dbus,manualresetevent,freedesktop.org,C#,Async Await,Dbus,Manualresetevent,Freedesktop.org,我对DBus的使用有问题 我试图通过几个动作按钮来获得一个通知泡泡 到目前为止,我已经能够让泡沫显现出来 retValue = await proxy.NotifyAsync( 并获取已在回调中按下的按钮 await proxy.WatchActionInvokedAsync 请参阅下面的代码 现在,由于通知在收到响应之前返回,所以我需要等待用户的响应(ManualResetEventSlim),然后再关闭连接 这造成了一个死锁,我通过切换到AsyncManualResetEvent解决了这

我对DBus的使用有问题
我试图通过几个动作按钮来获得一个通知泡泡

到目前为止,我已经能够让泡沫显现出来

retValue = await proxy.NotifyAsync(
并获取已在回调中按下的按钮

await proxy.WatchActionInvokedAsync
请参阅下面的代码

现在,由于通知在收到响应之前返回,所以我需要等待用户的响应(ManualResetEventSlim),然后再关闭连接
这造成了一个死锁,我通过切换到AsyncManualResetEvent解决了这个问题

现在它工作了,有点-我得到了冒泡,如果选择了冒泡操作(如果在超时之前单击-目前未处理超时),我会得到响应,但我也在WatchActionInvokedAsync中的OneError回调中传递了一个异常

错误回调:无法访问已释放的对象。对象名称:
'Tmds.DBus.Connection'

为什么会出现这个错误
不应
等待notifyResponseReceived.WaitAsync()在释放连接之前返回
什么可能导致此错误
除此之外,为什么异常有一个空的stacktrace

namespace NotificationTest
{


    // https://devblogs.microsoft.com/pfxteam/building-async-coordination-primitives-part-1-asyncmanualresetevent/
    public class AsyncManualResetEvent
    {
        private volatile System.Threading.Tasks.TaskCompletionSource<bool> m_tcs; 


        public AsyncManualResetEvent()
        {
            this.m_tcs = new System.Threading.Tasks.TaskCompletionSource<bool>();
        }


        public System.Threading.Tasks.Task WaitAsync() 
        { 
            return this.m_tcs.Task; 
        }


        //public void Set() 
        //{ 
        //    this.m_tcs.TrySetResult(true); 
        //}

        public void Set()
        {
            System.Threading.Tasks.TaskCompletionSource<bool> tcs = this.m_tcs;

            System.Threading.Tasks.Task.Factory.StartNew(s => ((System.Threading.Tasks.TaskCompletionSource<bool>)s).TrySetResult(true),
                tcs, System.Threading.CancellationToken.None, System.Threading.Tasks.TaskCreationOptions.PreferFairness, System.Threading.Tasks.TaskScheduler.Default);

            tcs.Task.Wait();
        }


        public void Reset()
        {
            while (true)
            {
                System.Threading.Tasks.TaskCompletionSource<bool> tcs = this.m_tcs;
                if (!tcs.Task.IsCompleted ||
                    System.Threading.Interlocked.CompareExchange(ref this.m_tcs, new System.Threading.Tasks.TaskCompletionSource<bool>(), tcs) == tcs)
                    return;
            } // Whend 

        } // End Sub Reset 


    } // End Class AsyncManualResetEvent



    class Program
    {


        // https://wiki.debianforum.de/Desktop-Notification_von_Systemservice_mittels_dbus
        // https://cheesehead-techblog.blogspot.com/2009/02/five-ways-to-make-notification-pop-up.html
        // https://wiki.debianforum.de/Desktop-Notification_von_Systemservice_mittels_dbus
        // https://gist.github.com/ducin/6152106
        // https://cweiske.de/tagebuch/DBus%20notify-send%20over%20network.htm
        // dotnet dbus list services --bus system | grep NetworkManager org.freedesktop.NetworkManager
        // dotnet dbus list objects --bus system --service org.freedesktop.NetworkManager
        // dotnet dbus codegen --bus system --service org.freedesktop.NetworkManager

        // cd ~/gitlab/Projects/NotificationTest/Tmds.DBus.Tool
        // dotnet run codegen --bus system --service org.freedesktop.NetworkManager
        // dotnet run codegen --bus session --service org.freedesktop.Notifications
        private static async System.Threading.Tasks.Task<uint> SendNotification()
        {
            uint retValue = 666;
            // System.Threading.ManualResetEventSlim notifyResponseReceived = new System.Threading.ManualResetEventSlim();
            AsyncManualResetEvent notifyResponseReceived = new AsyncManualResetEvent();

            Tmds.DBus.ObjectPath objectPath = new Tmds.DBus.ObjectPath("/org/freedesktop/Notifications");
            string service = "org.freedesktop.Notifications";

            using (Tmds.DBus.Connection connection = new Tmds.DBus.Connection(Tmds.DBus.Address.Session))
            {
                await connection.ConnectAsync();

                Notifications.DBus.INotifications proxy = connection.CreateProxy<Notifications.DBus.INotifications>(service, objectPath);

                // Task<IDisposable> WatchActionInvokedAsync(Action<(uint id, string actionKey)> handler, Action<Exception> onError = null);
                await proxy.WatchActionInvokedAsync(
                    delegate ((uint id, string actionKey) id)
                    {
                        if (id.id != retValue)
                        {
                            System.Console.WriteLine("abort");
                            return;
                        }

                        System.Console.WriteLine("Dialog Id: {0}", id.id);
                        System.Console.WriteLine($"ActionKey: {id.actionKey}");
                        notifyResponseReceived.Set();
                    }, delegate (System.Exception ex)
                    {
                        System.Console.Write("Error callback: ");
                        System.Console.WriteLine(ex.Message);
                        System.Console.WriteLine(ex.StackTrace);
                    }
                );


                // string[] actions = new string[0];
                string[] actions = new string[] { "0", "Cancel", "1", "No", "266789", "default", "3", "test" };

                System.Collections.Generic.Dictionary<string, object> hints =
                    new System.Collections.Generic.Dictionary<string, object>();

                string icon = "insert-image"; // # Siehe https://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html#names
                icon = "call-start";
                icon = "/root/Downloads/5d9ad698-8270-4141-b64e-736d3dbb9ecc.jpeg";
                icon = "dialog-information";
                icon = "dialog-error";
                icon = "dialog-warning";
                icon = "flag-ch";

                // https://developer.gnome.org/notification-spec/

                //await proxy.NotifyAsync("Notification", 0, icon, "summary", "body", actions, hints, 0);
                retValue = await proxy.NotifyAsync("Notifica1tion", 0, icon, "This is the summary", "This is the body", actions, hints, 5000);

                // notifyResponseReceived.Wait(); // blocks itselfs
                await notifyResponseReceived.WaitAsync();
            } // End Using connection 

            return retValue;
        } // End Task SendNotification 


        static void Main(string[] args)
        {
            System.Console.Write("Notification ID: ");
            System.Console.WriteLine(SendNotification().Result);
            System.Console.ReadKey();

            System.Console.WriteLine(" --- Press any key to continue --- ");
            System.Console.ReadKey();
        } // End Sub Main 


    } // End Class AsyncManualResetEvent 


} // End Namespace NotificationTest
namespace NotificationTest
{
// https://devblogs.microsoft.com/pfxteam/building-async-coordination-primitives-part-1-asyncmanualresetevent/
公共类异步重置事件
{
私有易失性System.Threading.Tasks.TaskCompletionSource m_tcs;
公共异步手动重置事件()
{
this.m_tcs=new System.Threading.Tasks.TaskCompletionSource();
}
public System.Threading.Tasks.Task WaitAsync()
{ 
返回此.m_tcs.Task;
}
//公共无效集()
//{ 
//此.m_tcs.TrySetResult(true);
//}
公共无效集()
{
System.Threading.Tasks.TaskCompletionSource tcs=this.m_tcs;
System.Threading.Tasks.Task.Factory.StartNew(s=>((System.Threading.Tasks.TaskCompletionSource)s).TrySetResult(true),
tcs、System.Threading.CancellationToken.None、System.Threading.Tasks.TaskCreationOptions.PreferFairity、System.Threading.Tasks.TaskScheduler.Default);
Task.Wait();
}
公共无效重置()
{
while(true)
{
System.Threading.Tasks.TaskCompletionSource tcs=this.m_tcs;
如果(!tcs.Task.IsCompleted||
System.Threading.Interlocated.CompareeExchange(参考this.m_tcs,new System.Threading.Tasks.TaskCompletionSource(),tcs)=tcs)
返回;
}//何时
}//结束子重置
}//结束类AsyncManualResetEvent
班级计划
{
// https://wiki.debianforum.de/Desktop-Notification_von_Systemservice_mittels_dbus
// https://cheesehead-techblog.blogspot.com/2009/02/five-ways-to-make-notification-pop-up.html
// https://wiki.debianforum.de/Desktop-Notification_von_Systemservice_mittels_dbus
// https://gist.github.com/ducin/6152106
// https://cweiske.de/tagebuch/DBus%20notify-通过%20network.htm发送%20
//dotnet dbus列表服务--总线系统| grep NetworkManager org.freedesktop.NetworkManager
//dotnet dbus列表对象--总线系统--服务org.freedesktop.NetworkManager
//dotnet dbus codegen--总线系统--服务org.freedesktop.NetworkManager
//cd~/gitlab/Projects/NotificationTest/Tmds.DBus.Tool
//dotnet运行codegen--总线系统--服务org.freedesktop.NetworkManager
//dotnet运行codegen--总线会话--服务org.freedesktop.Notifications
私有静态异步System.Threading.Tasks.Task SendNotification()
{
uint-retValue=666;
//System.Threading.ManualResetEventSlim notifyResponseReceived=新的System.Threading.ManualResetEventSlim();
AsyncManualResetEvent notifyResponseReceived=新的AsyncManualResetEvent();
Tmds.DBus.ObjectPath ObjectPath=new Tmds.DBus.ObjectPath(“/org/freedesktop/Notifications”);
string service=“org.freedesktop.Notifications”;
使用(Tmds.DBus.Connection Connection=newtmds.DBus.Connection(Tmds.DBus.Address.Session))
{
等待连接。ConnectAsync();
Notifications.DBus.INotifications proxy=connection.CreateProxy(服务,objectPath);
//任务WatchActionInvokedAsync(操作处理程序,操作onError=null);
等待proxy.WatchActionInvokedAsync(
委托((uint id,string actionKey)id)
{
如果(id.id!=retValue)
{
系统控制台写入线(“中止”);
返回;
}
System.Console.WriteLine(“对话框Id:{0}”,Id.Id);
System.Console.WriteLine($“ActionKey:{id.ActionKey}”);
notifyResponseReceived.Set();
},委托(System.Exception ex)
{
System.Console.Write(“错误回调:”);
系统控制台写入线(例如消息);
系统控制台写入线(例如StackTrace);
}
);
//string[]actions=新字符串[0];
字符串[]操作=新字符串[]{“0”、“取消”、“1”、“否”、“266789”、“默认”、“3”、“测试”};
System.Collections.Generic.Dictionary提示=
新的System.Collections.Generic.Dictionary();
string icon=“插入图像”/#Siehehttps://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html#names
icon=“呼叫开始”;
icon=“/root/Downloads/5d9ad698-8270-4141-b64e-736d3dbb9ecc.jpeg”;